Skip to content

Commit 973dd56

Browse files
committed
fix computing the offset of an unsized field in a packed struct
cc rust-lang/rust#118540 Fixes #1435
1 parent 1ab05b6 commit 973dd56

File tree

3 files changed

+14
-10
lines changed

3 files changed

+14
-10
lines changed

scripts/test_rustc_tests.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,6 @@ rm -r tests/run-make/extern-fn-explicit-align # argument alignment not yet suppo
140140

141141
rm tests/ui/codegen/subtyping-enforces-type-equality.rs # assert_assignable bug with Coroutine's
142142

143-
rm tests/ui/packed/issue-118537-field-offset-ice.rs # rust-lang/rust#118540
144-
145143
# bugs in the test suite
146144
# ======================
147145
rm tests/ui/backtrace.rs # TODO warning

src/unsize.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,7 @@ pub(crate) fn size_and_align_of<'tcx>(
274274
} else {
275275
// We have to dynamically compute `min(unsized_align, packed)`.
276276
let packed = fx.bcx.ins().iconst(fx.pointer_type, packed.bytes() as i64);
277-
let cmp =
278-
fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, unsized_align, packed);
277+
let cmp = fx.bcx.ins().icmp(IntCC::UnsignedLessThan, unsized_align, packed);
279278
unsized_align = fx.bcx.ins().select(cmp, unsized_align, packed);
280279
}
281280
}

src/value_and_place.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,22 @@ fn codegen_field<'tcx>(
2525
}
2626
match field_layout.ty.kind() {
2727
ty::Slice(..) | ty::Str => simple(fx),
28-
ty::Adt(def, _) if def.repr().packed() => {
29-
assert_eq!(layout.align.abi.bytes(), 1);
30-
simple(fx)
31-
}
3228
_ => {
33-
// We have to align the offset for DST's
3429
let unaligned_offset = field_offset.bytes();
35-
let (_, unsized_align) = crate::unsize::size_and_align_of(fx, field_layout, extra);
3630

31+
// Get the alignment of the field
32+
let (_, mut unsized_align) = crate::unsize::size_and_align_of(fx, field_layout, extra);
33+
34+
// For packed types, we need to cap alignment.
35+
if let ty::Adt(def, _) = layout.ty.kind() {
36+
if let Some(packed) = def.repr().pack {
37+
let packed = fx.bcx.ins().iconst(fx.pointer_type, packed.bytes() as i64);
38+
let cmp = fx.bcx.ins().icmp(IntCC::UnsignedLessThan, unsized_align, packed);
39+
unsized_align = fx.bcx.ins().select(cmp, unsized_align, packed);
40+
}
41+
}
42+
43+
// Bump the unaligned offset up to the appropriate alignment
3744
let one = fx.bcx.ins().iconst(fx.pointer_type, 1);
3845
let align_sub_1 = fx.bcx.ins().isub(unsized_align, one);
3946
let and_lhs = fx.bcx.ins().iadd_imm(align_sub_1, unaligned_offset as i64);

0 commit comments

Comments
 (0)