Skip to content

Commit 8a60d0a

Browse files
authored
Rollup merge of #101339 - the8472:ci-randomize-debug, r=Mark-Simulacrum
enable -Zrandomize-layout in debug CI builds This builds rustc/libs/tools with `-Zrandomize-layout` on *-debug CI runners. Only a handful of tests and asserts break with that enabled, which is promising. One test was fixable, the rest is dealt with by disabling them through new cargo features or compiletest directives. The config.toml flag `rust.randomize-layout` defaults to false, so it has to be explicitly enabled for now.
2 parents 009e738 + c218c75 commit 8a60d0a

29 files changed

Lines changed: 103 additions & 10 deletions

File tree

‎Cargo.lock‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3569,6 +3569,7 @@ dependencies = [
35693569
"rustc_hir_pretty",
35703570
"rustc_hir_typeck",
35713571
"rustc_incremental",
3572+
"rustc_index",
35723573
"rustc_infer",
35733574
"rustc_interface",
35743575
"rustc_lint",

‎compiler/rustc/Cargo.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@ features = ['unprefixed_malloc_on_supported_platforms']
3030
jemalloc = ['dep:jemalloc-sys']
3131
llvm = ['rustc_driver_impl/llvm']
3232
max_level_info = ['rustc_driver_impl/max_level_info']
33+
rustc_randomized_layouts = ['rustc_driver_impl/rustc_randomized_layouts']
3334
rustc_use_parallel_compiler = ['rustc_driver_impl/rustc_use_parallel_compiler']
3435
# tidy-alphabetical-end

‎compiler/rustc_abi/src/layout.rs‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -968,8 +968,8 @@ fn univariant<
968968
letmut align = if pack.is_some(){ dl.i8_align}else{ dl.aggregate_align};
969969
letmut max_repr_align = repr.align;
970970
letmut inverse_memory_index:IndexVec<u32,FieldIdx> = fields.indices().collect();
971-
letoptimize = !repr.inhibit_struct_field_reordering();
972-
ifoptimize && fields.len() > 1{
971+
letoptimize_field_order = !repr.inhibit_struct_field_reordering();
972+
ifoptimize_field_order && fields.len() > 1{
973973
let end = ifletStructKind::MaybeUnsized = kind { fields.len() - 1}else{ fields.len()};
974974
let optimizing = &mut inverse_memory_index.raw[..end];
975975
let fields_excluding_tail = &fields.raw[..end];
@@ -1176,7 +1176,7 @@ fn univariant<
11761176
// If field 5 has offset 0, offsets[0] is 5, and memory_index[5] should be 0.
11771177
// Field 5 would be the first element, so memory_index is i:
11781178
// Note: if we didn't optimize, it's already right.
1179-
let memory_index = ifoptimize{
1179+
let memory_index = ifoptimize_field_order{
11801180
inverse_memory_index.invert_bijective_mapping()
11811181
}else{
11821182
debug_assert!(inverse_memory_index.iter().copied().eq(fields.indices()));
@@ -1189,6 +1189,9 @@ fn univariant<
11891189
}
11901190
letmut layout_of_single_non_zst_field = None;
11911191
letmut abi = Abi::Aggregate{ sized };
1192+
1193+
let optimize_abi = !repr.inhibit_newtype_abi_optimization();
1194+
11921195
// Try to make this a Scalar/ScalarPair.
11931196
if sized && size.bytes() > 0{
11941197
// We skip *all* ZST here and later check if we are good in terms of alignment.
@@ -1205,7 +1208,7 @@ fn univariant<
12051208
match field.abi{
12061209
// For plain scalars, or vectors of them, we can't unpack
12071210
// newtypes for `#[repr(C)]`, as that affects C ABIs.
1208-
Abi::Scalar(_) | Abi::Vector{ .. }ifoptimize => {
1211+
Abi::Scalar(_) | Abi::Vector{ .. }ifoptimize_abi => {
12091212
abi = field.abi;
12101213
}
12111214
// But scalar pairs are Rust-specific and get

‎compiler/rustc_abi/src/lib.rs‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,17 @@ bitflags! {
4343
constIS_SIMD = 1 << 1;
4444
constIS_TRANSPARENT = 1 << 2;
4545
// Internal only for now. If true, don't reorder fields.
46+
// On its own it does not prevent ABI optimizations.
4647
constIS_LINEAR = 1 << 3;
47-
// If true, the type's layout can be randomized using
48-
// the seed stored in `ReprOptions.field_shuffle_seed`
48+
// If true, the type's crate has opted into layout randomization.
49+
// Other flags can still inhibit reordering and thus randomization.
50+
// The seed stored in `ReprOptions.field_shuffle_seed`.
4951
constRANDOMIZE_LAYOUT = 1 << 4;
5052
// Any of these flags being set prevent field reordering optimisation.
51-
constIS_UNOPTIMISABLE = ReprFlags::IS_C.bits()
53+
constFIELD_ORDER_UNOPTIMIZABLE = ReprFlags::IS_C.bits()
5254
| ReprFlags::IS_SIMD.bits()
5355
| ReprFlags::IS_LINEAR.bits();
56+
constABI_UNOPTIMIZABLE = ReprFlags::IS_C.bits() | ReprFlags::IS_SIMD.bits();
5457
}
5558
}
5659

@@ -139,10 +142,14 @@ impl ReprOptions {
139142
self.c() || self.int.is_some()
140143
}
141144

145+
pubfninhibit_newtype_abi_optimization(&self) -> bool{
146+
self.flags.intersects(ReprFlags::ABI_UNOPTIMIZABLE)
147+
}
148+
142149
/// Returns `true` if this `#[repr()]` guarantees a fixed field order,
143150
/// e.g. `repr(C)` or `repr(<int>)`.
144151
pubfninhibit_struct_field_reordering(&self) -> bool{
145-
self.flags.intersects(ReprFlags::IS_UNOPTIMISABLE) || self.int.is_some()
152+
self.flags.intersects(ReprFlags::FIELD_ORDER_UNOPTIMIZABLE) || self.int.is_some()
146153
}
147154

148155
/// Returns `true` if this type is valid for reordering and `-Z randomize-layout`

‎compiler/rustc_driver_impl/Cargo.toml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ rustc_hir_analysis = { path = "../rustc_hir_analysis" }
2323
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
2424
rustc_hir_typeck = { path = "../rustc_hir_typeck" }
2525
rustc_incremental = { path = "../rustc_incremental" }
26+
rustc_index = { path = "../rustc_index" }
2627
rustc_infer = { path = "../rustc_infer" }
2728
rustc_interface = { path = "../rustc_interface" }
2829
rustc_lint = { path = "../rustc_lint" }
@@ -72,6 +73,10 @@ ctrlc = "3.4.4"
7273
# tidy-alphabetical-start
7374
llvm = ['rustc_interface/llvm']
7475
max_level_info = ['rustc_log/max_level_info']
76+
rustc_randomized_layouts = [
77+
'rustc_index/rustc_randomized_layouts',
78+
'rustc_middle/rustc_randomized_layouts'
79+
]
7580
rustc_use_parallel_compiler = [
7681
'rustc_data_structures/rustc_use_parallel_compiler',
7782
'rustc_interface/rustc_use_parallel_compiler',

‎compiler/rustc_index/Cargo.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ nightly = [
2020
"dep:rustc_macros",
2121
"rustc_index_macros/nightly",
2222
]
23+
rustc_randomized_layouts = []
2324
# tidy-alphabetical-end

‎compiler/rustc_index/src/lib.rs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,19 @@ pub use vec::IndexVec;
3333
///
3434
/// </div>
3535
#[macro_export]
36+
#[cfg(not(feature = "rustc_randomized_layouts"))]
3637
macro_rules! static_assert_size {
3738
($ty:ty, $size:expr) => {
3839
const _:[(); $size] = [();::std::mem::size_of::<$ty>()];
3940
};
4041
}
42+
43+
#[macro_export]
44+
#[cfg(feature = "rustc_randomized_layouts")]
45+
macro_rules! static_assert_size {
46+
($ty:ty, $size:expr) => {
47+
// no effect other than using the statements.
48+
// struct sizes are not deterministic under randomized layouts
49+
const _:(usize,usize) = ($size,::std::mem::size_of::<$ty>());
50+
};
51+
}

‎compiler/rustc_middle/Cargo.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,6 @@ tracing = "0.1"
4040

4141
[features]
4242
# tidy-alphabetical-start
43+
rustc_randomized_layouts = []
4344
rustc_use_parallel_compiler = ["dep:rustc-rayon-core"]
4445
# tidy-alphabetical-end

‎compiler/rustc_middle/src/query/plumbing.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ macro_rules! define_callbacks {
337337
// Ensure that values grow no larger than 64 bytes by accident.
338338
// Increase this limit if necessary, but do try to keep the size low if possible
339339
#[cfg(target_pointer_width = "64")]
340+
#[cfg(not(feature = "rustc_randomized_layouts"))]
340341
const _:() = {
341342
if mem::size_of::<Value<'static>>() > 64{
342343
panic!("{}", concat!(

‎compiler/rustc_middle/src/ty/mod.rs‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
3535
use rustc_errors::{Diag,ErrorGuaranteed,StashKey};
3636
use rustc_hir::def::{CtorKind,CtorOf,DefKind,DocLinkResMap,LifetimeRes,Res};
3737
use rustc_hir::def_id::{CrateNum,DefId,DefIdMap,LocalDefId,LocalDefIdMap};
38+
use rustc_hir::LangItem;
3839
use rustc_index::IndexVec;
3940
use rustc_macros::{
4041
extension,Decodable,Encodable,HashStable,TyDecodable,TyEncodable,TypeFoldable,
@@ -1570,8 +1571,15 @@ impl<'tcx> TyCtxt<'tcx> {
15701571
flags.insert(ReprFlags::RANDOMIZE_LAYOUT);
15711572
}
15721573

1574+
// box is special, on the one hand the compiler assumes an ordered layout, with the pointer
1575+
// always at offset zero. On the other hand we want scalar abi optimizations.
1576+
let is_box = self.is_lang_item(did.to_def_id(),LangItem::OwnedBox);
1577+
15731578
// This is here instead of layout because the choice must make it into metadata.
1574-
if !self.consider_optimizing(|| format!("Reorder fields of {:?}",self.def_path_str(did))){
1579+
if is_box
1580+
|| !self
1581+
.consider_optimizing(|| format!("Reorder fields of {:?}",self.def_path_str(did)))
1582+
{
15751583
flags.insert(ReprFlags::IS_LINEAR);
15761584
}
15771585

0 commit comments

Comments
 (0)