@@ -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
@@ -222,6 +225,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
222
225
size : Size :: ZERO ,
223
226
max_repr_align : None ,
224
227
unadjusted_abi_align : dl. i8_align . abi ,
228
+ randomization_seed : 0 ,
225
229
}
226
230
}
227
231
@@ -384,6 +388,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
384
388
return Err ( LayoutCalculatorError :: EmptyUnion ) ;
385
389
} ;
386
390
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
+
387
396
Ok ( LayoutData {
388
397
variants : Variants :: Single { index : only_variant_idx } ,
389
398
fields : FieldsShape :: Union ( union_field_count) ,
@@ -393,6 +402,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
393
402
size : size. align_to ( align. abi ) ,
394
403
max_repr_align,
395
404
unadjusted_abi_align,
405
+ randomization_seed : combined_seed,
396
406
} )
397
407
}
398
408
@@ -649,6 +659,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
649
659
BackendRepr :: Memory { sized : true }
650
660
} ;
651
661
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
+
652
667
let layout = LayoutData {
653
668
variants : Variants :: Multiple {
654
669
tag : niche_scalar,
@@ -670,6 +685,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
670
685
align,
671
686
max_repr_align,
672
687
unadjusted_abi_align,
688
+ randomization_seed : combined_seed,
673
689
} ;
674
690
675
691
Some ( TmpLayout { layout, variants : variant_layouts } )
@@ -960,6 +976,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
960
976
961
977
let largest_niche = Niche :: from_scalar ( dl, Size :: ZERO , tag) ;
962
978
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
+
963
984
let tagged_layout = LayoutData {
964
985
variants : Variants :: Multiple {
965
986
tag,
@@ -977,6 +998,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
977
998
size,
978
999
max_repr_align,
979
1000
unadjusted_abi_align,
1001
+ randomization_seed : combined_seed,
980
1002
} ;
981
1003
982
1004
let tagged_layout = TmpLayout { layout : tagged_layout, variants : layout_variants } ;
@@ -1029,12 +1051,14 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
1029
1051
let mut max_repr_align = repr. align ;
1030
1052
let mut inverse_memory_index: IndexVec < u32 , FieldIdx > = fields. indices ( ) . collect ( ) ;
1031
1053
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 ) ) ;
1037
1060
1061
+ if optimize_field_order && fields. len ( ) > 1 {
1038
1062
// If `-Z randomize-layout` was enabled for the type definition we can shuffle
1039
1063
// the field ordering to try and catch some code making assumptions about layouts
1040
1064
// we don't guarantee.
@@ -1043,10 +1067,12 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
1043
1067
{
1044
1068
use rand:: SeedableRng ;
1045
1069
use rand:: seq:: SliceRandom ;
1070
+ //let field_entropy = fields_excluding_tail.iter().map(|f| f.).sum();
1046
1071
// `ReprOptions.field_shuffle_seed` is a deterministic seed we can use to randomize field
1047
1072
// 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
+ ) ;
1050
1076
1051
1077
// Shuffle the ordering of the fields.
1052
1078
optimizing. shuffle ( & mut rng) ;
@@ -1343,6 +1369,14 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
1343
1369
unadjusted_abi_align
1344
1370
} ;
1345
1371
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
+
1346
1380
Ok ( LayoutData {
1347
1381
variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
1348
1382
fields : FieldsShape :: Arbitrary { offsets, memory_index } ,
@@ -1352,6 +1386,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
1352
1386
size,
1353
1387
max_repr_align,
1354
1388
unadjusted_abi_align,
1389
+ randomization_seed : seed,
1355
1390
} )
1356
1391
}
1357
1392
0 commit comments