@@ -119,6 +119,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
119
119
. chain ( Niche :: from_scalar ( dl, Size :: ZERO , a) )
120
120
. max_by_key ( |niche| niche. available ( dl) ) ;
121
121
122
+ let combined_seed = a. size ( & self . cx ) . bytes ( ) . wrapping_add ( b. size ( & self . cx ) . bytes ( ) ) ;
123
+
122
124
LayoutData {
123
125
variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
124
126
fields : FieldsShape :: Arbitrary {
@@ -131,6 +133,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
131
133
size,
132
134
max_repr_align : None ,
133
135
unadjusted_abi_align : align. abi ,
136
+ randomization_seed : combined_seed,
134
137
}
135
138
}
136
139
@@ -223,6 +226,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
223
226
size : Size :: ZERO ,
224
227
max_repr_align : None ,
225
228
unadjusted_abi_align : dl. i8_align . abi ,
229
+ randomization_seed : 0 ,
226
230
}
227
231
}
228
232
@@ -385,6 +389,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
385
389
return Err ( LayoutCalculatorError :: EmptyUnion ) ;
386
390
} ;
387
391
392
+ let combined_seed = only_variant
393
+ . iter ( )
394
+ . map ( |v| v. randomization_seed )
395
+ . fold ( repr. field_shuffle_seed , |acc, seed| acc. wrapping_add ( seed) ) ;
396
+
388
397
Ok ( LayoutData {
389
398
variants : Variants :: Single { index : only_variant_idx } ,
390
399
fields : FieldsShape :: Union ( union_field_count) ,
@@ -394,6 +403,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
394
403
size : size. align_to ( align. abi ) ,
395
404
max_repr_align,
396
405
unadjusted_abi_align,
406
+ randomization_seed : combined_seed,
397
407
} )
398
408
}
399
409
@@ -650,6 +660,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
650
660
BackendRepr :: Memory { sized : true }
651
661
} ;
652
662
663
+ let combined_seed = variant_layouts
664
+ . iter ( )
665
+ . map ( |v| v. randomization_seed )
666
+ . fold ( repr. field_shuffle_seed , |acc, seed| acc. wrapping_add ( seed) ) ;
667
+
653
668
let layout = LayoutData {
654
669
variants : Variants :: Multiple {
655
670
tag : niche_scalar,
@@ -671,6 +686,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
671
686
align,
672
687
max_repr_align,
673
688
unadjusted_abi_align,
689
+ randomization_seed : combined_seed,
674
690
} ;
675
691
676
692
Some ( TmpLayout { layout, variants : variant_layouts } )
@@ -961,6 +977,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
961
977
962
978
let largest_niche = Niche :: from_scalar ( dl, Size :: ZERO , tag) ;
963
979
980
+ let combined_seed = layout_variants
981
+ . iter ( )
982
+ . map ( |v| v. randomization_seed )
983
+ . fold ( repr. field_shuffle_seed , |acc, seed| acc. wrapping_add ( seed) ) ;
984
+
964
985
let tagged_layout = LayoutData {
965
986
variants : Variants :: Multiple {
966
987
tag,
@@ -978,6 +999,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
978
999
size,
979
1000
max_repr_align,
980
1001
unadjusted_abi_align,
1002
+ randomization_seed : combined_seed,
981
1003
} ;
982
1004
983
1005
let tagged_layout = TmpLayout { layout : tagged_layout, variants : layout_variants } ;
@@ -1030,12 +1052,15 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
1030
1052
let mut max_repr_align = repr. align ;
1031
1053
let mut inverse_memory_index: IndexVec < u32 , FieldIdx > = fields. indices ( ) . collect ( ) ;
1032
1054
let optimize_field_order = !repr. inhibit_struct_field_reordering ( ) ;
1033
- if optimize_field_order && fields. len ( ) > 1 {
1034
- let end =
1035
- if let StructKind :: MaybeUnsized = kind { fields. len ( ) - 1 } else { fields. len ( ) } ;
1036
- let optimizing = & mut inverse_memory_index. raw [ ..end] ;
1037
- 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 ) ) ;
1038
1062
1063
+ if optimize_field_order && fields. len ( ) > 1 {
1039
1064
// If `-Z randomize-layout` was enabled for the type definition we can shuffle
1040
1065
// the field ordering to try and catch some code making assumptions about layouts
1041
1066
// we don't guarantee.
@@ -1046,8 +1071,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
1046
1071
use rand:: seq:: SliceRandom ;
1047
1072
// `ReprOptions.field_shuffle_seed` is a deterministic seed we can use to randomize field
1048
1073
// ordering.
1049
- let mut rng =
1050
- rand_xoshiro:: Xoshiro128StarStar :: seed_from_u64 ( repr. field_shuffle_seed ) ;
1074
+ let mut rng = rand_xoshiro:: Xoshiro128StarStar :: seed_from_u64 (
1075
+ field_seed. wrapping_add ( repr. field_shuffle_seed ) ,
1076
+ ) ;
1051
1077
1052
1078
// Shuffle the ordering of the fields.
1053
1079
optimizing. shuffle ( & mut rng) ;
@@ -1344,6 +1370,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
1344
1370
unadjusted_abi_align
1345
1371
} ;
1346
1372
1373
+ let seed = field_seed. wrapping_add ( repr. field_shuffle_seed ) ;
1374
+
1347
1375
Ok ( LayoutData {
1348
1376
variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
1349
1377
fields : FieldsShape :: Arbitrary { offsets, memory_index } ,
@@ -1353,6 +1381,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
1353
1381
size,
1354
1382
max_repr_align,
1355
1383
unadjusted_abi_align,
1384
+ randomization_seed : seed,
1356
1385
} )
1357
1386
}
1358
1387
0 commit comments