about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2023-12-18 18:12:29 +0000
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2023-12-18 18:12:29 +0000
commit973dd562e826a0db422a9fbf34de960ec3465577 (patch)
treed6defcad1fecde16b1a076545e813ac9d3773ba2
parent1ab05b6cbe265ab239262a119817a2b77698c640 (diff)
downloadrust-973dd562e826a0db422a9fbf34de960ec3465577.tar.gz
rust-973dd562e826a0db422a9fbf34de960ec3465577.zip
fix computing the offset of an unsized field in a packed struct
cc rust-lang/rust#118540
Fixes rust-lang/rustc_codegen_cranelift#1435
-rwxr-xr-xscripts/test_rustc_tests.sh2
-rw-r--r--src/unsize.rs3
-rw-r--r--src/value_and_place.rs19
3 files changed, 14 insertions, 10 deletions
diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh
index c79ee4399e2..7d7ffdadc7f 100755
--- a/scripts/test_rustc_tests.sh
+++ b/scripts/test_rustc_tests.sh
@@ -140,8 +140,6 @@ rm -r tests/run-make/extern-fn-explicit-align # argument alignment not yet suppo
 
 rm tests/ui/codegen/subtyping-enforces-type-equality.rs # assert_assignable bug with Coroutine's
 
-rm tests/ui/packed/issue-118537-field-offset-ice.rs # rust-lang/rust#118540
-
 # bugs in the test suite
 # ======================
 rm tests/ui/backtrace.rs # TODO warning
diff --git a/src/unsize.rs b/src/unsize.rs
index c65a79cb654..f777e11371f 100644
--- a/src/unsize.rs
+++ b/src/unsize.rs
@@ -274,8 +274,7 @@ pub(crate) fn size_and_align_of<'tcx>(
                     } else {
                         // We have to dynamically compute `min(unsized_align, packed)`.
                         let packed = fx.bcx.ins().iconst(fx.pointer_type, packed.bytes() as i64);
-                        let cmp =
-                            fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, unsized_align, packed);
+                        let cmp = fx.bcx.ins().icmp(IntCC::UnsignedLessThan, unsized_align, packed);
                         unsized_align = fx.bcx.ins().select(cmp, unsized_align, packed);
                     }
                 }
diff --git a/src/value_and_place.rs b/src/value_and_place.rs
index 2270193ebb1..567a5669d49 100644
--- a/src/value_and_place.rs
+++ b/src/value_and_place.rs
@@ -25,15 +25,22 @@ fn codegen_field<'tcx>(
     }
     match field_layout.ty.kind() {
         ty::Slice(..) | ty::Str => simple(fx),
-        ty::Adt(def, _) if def.repr().packed() => {
-            assert_eq!(layout.align.abi.bytes(), 1);
-            simple(fx)
-        }
         _ => {
-            // We have to align the offset for DST's
             let unaligned_offset = field_offset.bytes();
-            let (_, unsized_align) = crate::unsize::size_and_align_of(fx, field_layout, extra);
 
+            // Get the alignment of the field
+            let (_, mut unsized_align) = crate::unsize::size_and_align_of(fx, field_layout, extra);
+
+            // For packed types, we need to cap alignment.
+            if let ty::Adt(def, _) = layout.ty.kind() {
+                if let Some(packed) = def.repr().pack {
+                    let packed = fx.bcx.ins().iconst(fx.pointer_type, packed.bytes() as i64);
+                    let cmp = fx.bcx.ins().icmp(IntCC::UnsignedLessThan, unsized_align, packed);
+                    unsized_align = fx.bcx.ins().select(cmp, unsized_align, packed);
+                }
+            }
+
+            // Bump the unaligned offset up to the appropriate alignment
             let one = fx.bcx.ins().iconst(fx.pointer_type, 1);
             let align_sub_1 = fx.bcx.ins().isub(unsized_align, one);
             let and_lhs = fx.bcx.ins().iadd_imm(align_sub_1, unaligned_offset as i64);