]> git.lizzy.rs Git - rust.git/commitdiff
make sure we only guess field alignment at offset 0
authorRalf Jung <post@ralfj.de>
Tue, 6 Nov 2018 07:41:56 +0000 (08:41 +0100)
committerRalf Jung <post@ralfj.de>
Tue, 6 Nov 2018 07:41:56 +0000 (08:41 +0100)
src/librustc_mir/interpret/eval_context.rs
src/librustc_mir/interpret/place.rs

index 797e0458e5312d37554ea82da5eb689fa7c3f3fa..cca4e8a3ce31a7672c90506d8f06c76412c3be37 100644 (file)
@@ -374,13 +374,12 @@ pub(super) fn size_and_align_of(
                 let (unsized_size, unsized_align) = match self.size_and_align_of(metadata, field)? {
                     Some(size_and_align) => size_and_align,
                     None => {
-                        // A field with extern type.  If this field is at offset 0 and the sized
-                        // part makes no alignment constraints, we behave like the underlying
-                        // extern type.
+                        // A field with extern type.  If this field is at offset 0, we behave
+                        // like the underlying extern type.
                         // FIXME: Once we have made decisions for how to handle size and alignment
                         // of `extern type`, this should be adapted.  It is just a temporary hack
                         // to get some code to work that probably ought to work.
-                        if sized_size == Size::ZERO && sized_align.abi() == 1 {
+                        if sized_size == Size::ZERO {
                             return Ok(None)
                         } else {
                             bug!("Fields cannot be extern types, unless they are at offset 0")
index c60ae7b4a00c4caf4a3b0e8e2095080991cd8def..a836a199f768da0d91341f0409346c9b95789c06 100644 (file)
@@ -353,13 +353,17 @@ pub fn mplace_field(
         // Offset may need adjustment for unsized fields
         let (meta, offset) = if field_layout.is_unsized() {
             // re-use parent metadata to determine dynamic field layout
-            let align = self.size_and_align_of(base.meta, field_layout)?
-                .map(|(_, align)| align)
-                // If this is an extern type, we fall back to its static alignment.
-                // FIXME: Once we have made decisions for how to handle size and alignment
-                // of `extern type`, this should be adapted.  It is just a temporary hack
-                // to get some code to work that probably ought to work.
-                .unwrap_or_else(|| base.layout.align);
+            let align = match self.size_and_align_of(base.meta, field_layout)? {
+                Some((_, align)) => align,
+                None if offset == Size::ZERO =>
+                    // An extern type at offset 0, we fall back to its static alignment.
+                    // FIXME: Once we have made decisions for how to handle size and alignment
+                    // of `extern type`, this should be adapted.  It is just a temporary hack
+                    // to get some code to work that probably ought to work.
+                    field_layout.align,
+                None =>
+                    bug!("Cannot compute offset for extern type field at non-0 offset"),
+            };
             (base.meta, offset.abi_align(align))
         } else {
             // base.meta could be present; we might be accessing a sized field of an unsized