diff options
| author | bjorn3 <17426603+bjorn3@users.noreply.github.com> | 2023-12-18 18:12:29 +0000 |
|---|---|---|
| committer | bjorn3 <17426603+bjorn3@users.noreply.github.com> | 2023-12-18 18:12:29 +0000 |
| commit | 973dd562e826a0db422a9fbf34de960ec3465577 (patch) | |
| tree | d6defcad1fecde16b1a076545e813ac9d3773ba2 | |
| parent | 1ab05b6cbe265ab239262a119817a2b77698c640 (diff) | |
| download | rust-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-x | scripts/test_rustc_tests.sh | 2 | ||||
| -rw-r--r-- | src/unsize.rs | 3 | ||||
| -rw-r--r-- | src/value_and_place.rs | 19 |
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); |
