@@ -119,6 +119,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
119119 . chain ( Niche :: from_scalar ( dl, Size :: ZERO , a) )
120120 . max_by_key ( |niche| niche. available ( dl) ) ;
121121
122+ let combined_seed = a. size ( & self . cx ) . bytes ( ) . wrapping_add ( b. size ( & self . cx ) . bytes ( ) ) ;
123+
122124 LayoutData {
123125 variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
124126 fields : FieldsShape :: Arbitrary {
@@ -131,6 +133,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
131133 size,
132134 max_repr_align : None ,
133135 unadjusted_abi_align : align. abi ,
136+ randomization_seed : combined_seed,
134137 }
135138 }
136139
@@ -222,6 +225,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
222225 size : Size :: ZERO ,
223226 max_repr_align : None ,
224227 unadjusted_abi_align : dl. i8_align . abi ,
228+ randomization_seed : 0 ,
225229 }
226230 }
227231
@@ -384,6 +388,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
384388 return Err ( LayoutCalculatorError :: EmptyUnion ) ;
385389 } ;
386390
391+ let combined_seed = only_variant
392+ . iter ( )
393+ . map ( |v| v. randomization_seed )
394+ . fold ( repr. field_shuffle_seed , |acc, seed| acc. wrapping_add ( seed) ) ;
395+
387396 Ok ( LayoutData {
388397 variants : Variants :: Single { index : only_variant_idx } ,
389398 fields : FieldsShape :: Union ( union_field_count) ,
@@ -393,6 +402,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
393402 size : size. align_to ( align. abi ) ,
394403 max_repr_align,
395404 unadjusted_abi_align,
405+ randomization_seed : combined_seed,
396406 } )
397407 }
398408
@@ -649,6 +659,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
649659 BackendRepr :: Memory { sized : true }
650660 } ;
651661
662+ let combined_seed = variant_layouts
663+ . iter ( )
664+ . map ( |v| v. randomization_seed )
665+ . fold ( repr. field_shuffle_seed , |acc, seed| acc. wrapping_add ( seed) ) ;
666+
652667 let layout = LayoutData {
653668 variants : Variants :: Multiple {
654669 tag : niche_scalar,
@@ -670,6 +685,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
670685 align,
671686 max_repr_align,
672687 unadjusted_abi_align,
688+ randomization_seed : combined_seed,
673689 } ;
674690
675691 Some ( TmpLayout { layout, variants : variant_layouts } )
@@ -960,6 +976,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
960976
961977 let largest_niche = Niche :: from_scalar ( dl, Size :: ZERO , tag) ;
962978
979+ let combined_seed = layout_variants
980+ . iter ( )
981+ . map ( |v| v. randomization_seed )
982+ . fold ( repr. field_shuffle_seed , |acc, seed| acc. wrapping_add ( seed) ) ;
983+
963984 let tagged_layout = LayoutData {
964985 variants : Variants :: Multiple {
965986 tag,
@@ -977,6 +998,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
977998 size,
978999 max_repr_align,
9791000 unadjusted_abi_align,
1001+ randomization_seed : combined_seed,
9801002 } ;
9811003
9821004 let tagged_layout = TmpLayout { layout : tagged_layout, variants : layout_variants } ;
@@ -1029,12 +1051,14 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
10291051 let mut max_repr_align = repr. align ;
10301052 let mut inverse_memory_index: IndexVec < u32 , FieldIdx > = fields. indices ( ) . collect ( ) ;
10311053 let optimize_field_order = !repr. inhibit_struct_field_reordering ( ) ;
1032- if optimize_field_order && fields. len ( ) > 1 {
1033- let end =
1034- if let StructKind :: MaybeUnsized = kind { fields. len ( ) - 1 } else { fields. len ( ) } ;
1035- let optimizing = & mut inverse_memory_index. raw [ ..end] ;
1036- let fields_excluding_tail = & fields. raw [ ..end] ;
1054+ let end = if let StructKind :: MaybeUnsized = kind { fields. len ( ) - 1 } else { fields. len ( ) } ;
1055+ let optimizing = & mut inverse_memory_index. raw [ ..end] ;
1056+ let fields_excluding_tail = & fields. raw [ ..end] ;
1057+ let field_seed = fields_excluding_tail
1058+ . iter ( )
1059+ . fold ( 0u64 , |acc, f| acc. wrapping_add ( f. randomization_seed ) ) ;
10371060
1061+ if optimize_field_order && fields. len ( ) > 1 {
10381062 // If `-Z randomize-layout` was enabled for the type definition we can shuffle
10391063 // the field ordering to try and catch some code making assumptions about layouts
10401064 // we don't guarantee.
@@ -1043,10 +1067,12 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
10431067 {
10441068 use rand:: SeedableRng ;
10451069 use rand:: seq:: SliceRandom ;
1070+ //let field_entropy = fields_excluding_tail.iter().map(|f| f.).sum();
10461071 // `ReprOptions.field_shuffle_seed` is a deterministic seed we can use to randomize field
10471072 // ordering.
1048- let mut rng =
1049- rand_xoshiro:: Xoshiro128StarStar :: seed_from_u64 ( repr. field_shuffle_seed ) ;
1073+ let mut rng = rand_xoshiro:: Xoshiro128StarStar :: seed_from_u64 (
1074+ field_seed. wrapping_add ( repr. field_shuffle_seed ) ,
1075+ ) ;
10501076
10511077 // Shuffle the ordering of the fields.
10521078 optimizing. shuffle ( & mut rng) ;
@@ -1343,6 +1369,14 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
13431369 unadjusted_abi_align
13441370 } ;
13451371
1372+ // a transparent struct only has a single field, so its seed should be the same as the one we pass forward
1373+ // if the field is also unsizable then we pass zero, which is the identity-element wrapping-add used for seed mixing
1374+ let seed = if repr. transparent ( ) {
1375+ field_seed
1376+ } else {
1377+ field_seed. wrapping_add ( repr. field_shuffle_seed )
1378+ } ;
1379+
13461380 Ok ( LayoutData {
13471381 variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
13481382 fields : FieldsShape :: Arbitrary { offsets, memory_index } ,
@@ -1352,6 +1386,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
13521386 size,
13531387 max_repr_align,
13541388 unadjusted_abi_align,
1389+ randomization_seed : seed,
13551390 } )
13561391 }
13571392
0 commit comments