Skip to content

Commit 253ef78

Browse files
committed
exclude unsizable tail from randomization seed calculation
1 parent 836c249 commit 253ef78

File tree

2 files changed

+13
-16
lines changed

2 files changed

+13
-16
lines changed

compiler/rustc_abi/src/layout.rs

+9-13
Original file line numberDiff line numberDiff line change
@@ -1051,15 +1051,16 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
10511051
let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
10521052
let mut max_repr_align = repr.align;
10531053
let mut inverse_memory_index: IndexVec<u32, FieldIdx> = fields.indices().collect();
1054-
let field_seed =
1055-
fields.raw.iter().fold(0u64, |acc, f| acc.wrapping_add(f.randomization_seed));
10561054
let optimize_field_order = !repr.inhibit_struct_field_reordering();
1057-
if optimize_field_order && fields.len() > 1 {
1058-
let end =
1059-
if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
1060-
let optimizing = &mut inverse_memory_index.raw[..end];
1061-
let fields_excluding_tail = &fields.raw[..end];
1055+
let end = if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
1056+
let optimizing = &mut inverse_memory_index.raw[..end];
1057+
let fields_excluding_tail = &fields.raw[..end];
1058+
// unsizable tail fields are excluded so that we use the same seed for the sized and unsized layouts.
1059+
let field_seed = fields_excluding_tail
1060+
.iter()
1061+
.fold(0u64, |acc, f| acc.wrapping_add(f.randomization_seed));
10621062

1063+
if optimize_field_order && fields.len() > 1 {
10631064
// If `-Z randomize-layout` was enabled for the type definition we can shuffle
10641065
// the field ordering to try and catch some code making assumptions about layouts
10651066
// we don't guarantee.
@@ -1369,12 +1370,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
13691370
unadjusted_abi_align
13701371
};
13711372

1372-
// a transparent struct only has a single field, so its seed should be the same as the one we pass forward
1373-
let seed = if repr.transparent() {
1374-
field_seed
1375-
} else {
1376-
field_seed.wrapping_add(repr.field_shuffle_seed)
1377-
};
1373+
let seed = field_seed.wrapping_add(repr.field_shuffle_seed);
13781374

13791375
Ok(LayoutData {
13801376
variants: Variants::Single { index: VariantIdx::new(0) },

tests/ui/layout/randomize.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ const _: () = {
2020
#[cfg(randomize_layout)]
2121
assert!(std::mem::offset_of!(Foo::<u16>, 1) != std::mem::offset_of!(Foo::<Wrapper<u16>>, 1));
2222

23-
// but repr(transparent) should make them the same again.
24-
// maybe not strictly guaranteed? but UCG has been leaning in that direction at least
23+
// Even transparent wrapper inner types get a different layout since associated type
24+
// pecialization could result in the outer type behaving differently depending on the exact
25+
// inner type.
2526
#[cfg(randomize_layout)]
2627
assert!(
27-
std::mem::offset_of!(Foo::<u16>, 1) == std::mem::offset_of!(Foo::<TransparentWrapper>, 1)
28+
std::mem::offset_of!(Foo::<u16>, 1) != std::mem::offset_of!(Foo::<TransparentWrapper>, 1)
2829
);
2930
};

0 commit comments

Comments
 (0)