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.
This commit is contained in:
Matthias Krüger 2024-09-05 03:47:39 +02:00 committed by GitHub
commit 8a60d0a5ec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 103 additions and 10 deletions

View File

@ -3569,6 +3569,7 @@ dependencies = [
"rustc_hir_pretty", "rustc_hir_pretty",
"rustc_hir_typeck", "rustc_hir_typeck",
"rustc_incremental", "rustc_incremental",
"rustc_index",
"rustc_infer", "rustc_infer",
"rustc_interface", "rustc_interface",
"rustc_lint", "rustc_lint",

View File

@ -30,5 +30,6 @@ features = ['unprefixed_malloc_on_supported_platforms']
jemalloc = ['dep:jemalloc-sys'] jemalloc = ['dep:jemalloc-sys']
llvm = ['rustc_driver_impl/llvm'] llvm = ['rustc_driver_impl/llvm']
max_level_info = ['rustc_driver_impl/max_level_info'] max_level_info = ['rustc_driver_impl/max_level_info']
rustc_randomized_layouts = ['rustc_driver_impl/rustc_randomized_layouts']
rustc_use_parallel_compiler = ['rustc_driver_impl/rustc_use_parallel_compiler'] rustc_use_parallel_compiler = ['rustc_driver_impl/rustc_use_parallel_compiler']
# tidy-alphabetical-end # tidy-alphabetical-end

View File

@ -968,8 +968,8 @@ fn univariant<
let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align }; let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
let mut max_repr_align = repr.align; let mut max_repr_align = repr.align;
let mut inverse_memory_index: IndexVec<u32, FieldIdx> = fields.indices().collect(); let mut inverse_memory_index: IndexVec<u32, FieldIdx> = fields.indices().collect();
let optimize = !repr.inhibit_struct_field_reordering(); let optimize_field_order = !repr.inhibit_struct_field_reordering();
if optimize && fields.len() > 1 { if optimize_field_order && fields.len() > 1 {
let end = if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() }; let end = if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
let optimizing = &mut inverse_memory_index.raw[..end]; let optimizing = &mut inverse_memory_index.raw[..end];
let fields_excluding_tail = &fields.raw[..end]; let fields_excluding_tail = &fields.raw[..end];
@ -1176,7 +1176,7 @@ fn univariant<
// If field 5 has offset 0, offsets[0] is 5, and memory_index[5] should be 0. // If field 5 has offset 0, offsets[0] is 5, and memory_index[5] should be 0.
// Field 5 would be the first element, so memory_index is i: // Field 5 would be the first element, so memory_index is i:
// Note: if we didn't optimize, it's already right. // Note: if we didn't optimize, it's already right.
let memory_index = if optimize { let memory_index = if optimize_field_order {
inverse_memory_index.invert_bijective_mapping() inverse_memory_index.invert_bijective_mapping()
} else { } else {
debug_assert!(inverse_memory_index.iter().copied().eq(fields.indices())); debug_assert!(inverse_memory_index.iter().copied().eq(fields.indices()));
@ -1189,6 +1189,9 @@ fn univariant<
} }
let mut layout_of_single_non_zst_field = None; let mut layout_of_single_non_zst_field = None;
let mut abi = Abi::Aggregate { sized }; let mut abi = Abi::Aggregate { sized };
let optimize_abi = !repr.inhibit_newtype_abi_optimization();
// Try to make this a Scalar/ScalarPair. // Try to make this a Scalar/ScalarPair.
if sized && size.bytes() > 0 { if sized && size.bytes() > 0 {
// We skip *all* ZST here and later check if we are good in terms of alignment. // We skip *all* ZST here and later check if we are good in terms of alignment.
@ -1205,7 +1208,7 @@ fn univariant<
match field.abi { match field.abi {
// For plain scalars, or vectors of them, we can't unpack // For plain scalars, or vectors of them, we can't unpack
// newtypes for `#[repr(C)]`, as that affects C ABIs. // newtypes for `#[repr(C)]`, as that affects C ABIs.
Abi::Scalar(_) | Abi::Vector { .. } if optimize => { Abi::Scalar(_) | Abi::Vector { .. } if optimize_abi => {
abi = field.abi; abi = field.abi;
} }
// But scalar pairs are Rust-specific and get // But scalar pairs are Rust-specific and get

View File

@ -43,14 +43,17 @@ impl ReprFlags: u8 {
const IS_SIMD = 1 << 1; const IS_SIMD = 1 << 1;
const IS_TRANSPARENT = 1 << 2; const IS_TRANSPARENT = 1 << 2;
// Internal only for now. If true, don't reorder fields. // Internal only for now. If true, don't reorder fields.
// On its own it does not prevent ABI optimizations.
const IS_LINEAR = 1 << 3; const IS_LINEAR = 1 << 3;
// If true, the type's layout can be randomized using // If true, the type's crate has opted into layout randomization.
// the seed stored in `ReprOptions.field_shuffle_seed` // Other flags can still inhibit reordering and thus randomization.
// The seed stored in `ReprOptions.field_shuffle_seed`.
const RANDOMIZE_LAYOUT = 1 << 4; const RANDOMIZE_LAYOUT = 1 << 4;
// Any of these flags being set prevent field reordering optimisation. // Any of these flags being set prevent field reordering optimisation.
const IS_UNOPTIMISABLE = ReprFlags::IS_C.bits() const FIELD_ORDER_UNOPTIMIZABLE = ReprFlags::IS_C.bits()
| ReprFlags::IS_SIMD.bits() | ReprFlags::IS_SIMD.bits()
| ReprFlags::IS_LINEAR.bits(); | ReprFlags::IS_LINEAR.bits();
const ABI_UNOPTIMIZABLE = ReprFlags::IS_C.bits() | ReprFlags::IS_SIMD.bits();
} }
} }
@ -139,10 +142,14 @@ pub fn inhibit_enum_layout_opt(&self) -> bool {
self.c() || self.int.is_some() self.c() || self.int.is_some()
} }
pub fn inhibit_newtype_abi_optimization(&self) -> bool {
self.flags.intersects(ReprFlags::ABI_UNOPTIMIZABLE)
}
/// Returns `true` if this `#[repr()]` guarantees a fixed field order, /// Returns `true` if this `#[repr()]` guarantees a fixed field order,
/// e.g. `repr(C)` or `repr(<int>)`. /// e.g. `repr(C)` or `repr(<int>)`.
pub fn inhibit_struct_field_reordering(&self) -> bool { pub fn inhibit_struct_field_reordering(&self) -> bool {
self.flags.intersects(ReprFlags::IS_UNOPTIMISABLE) || self.int.is_some() self.flags.intersects(ReprFlags::FIELD_ORDER_UNOPTIMIZABLE) || self.int.is_some()
} }
/// Returns `true` if this type is valid for reordering and `-Z randomize-layout` /// Returns `true` if this type is valid for reordering and `-Z randomize-layout`

View File

@ -23,6 +23,7 @@ rustc_hir_analysis = { path = "../rustc_hir_analysis" }
rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_hir_pretty = { path = "../rustc_hir_pretty" }
rustc_hir_typeck = { path = "../rustc_hir_typeck" } rustc_hir_typeck = { path = "../rustc_hir_typeck" }
rustc_incremental = { path = "../rustc_incremental" } rustc_incremental = { path = "../rustc_incremental" }
rustc_index = { path = "../rustc_index" }
rustc_infer = { path = "../rustc_infer" } rustc_infer = { path = "../rustc_infer" }
rustc_interface = { path = "../rustc_interface" } rustc_interface = { path = "../rustc_interface" }
rustc_lint = { path = "../rustc_lint" } rustc_lint = { path = "../rustc_lint" }
@ -72,6 +73,10 @@ ctrlc = "3.4.4"
# tidy-alphabetical-start # tidy-alphabetical-start
llvm = ['rustc_interface/llvm'] llvm = ['rustc_interface/llvm']
max_level_info = ['rustc_log/max_level_info'] max_level_info = ['rustc_log/max_level_info']
rustc_randomized_layouts = [
'rustc_index/rustc_randomized_layouts',
'rustc_middle/rustc_randomized_layouts'
]
rustc_use_parallel_compiler = [ rustc_use_parallel_compiler = [
'rustc_data_structures/rustc_use_parallel_compiler', 'rustc_data_structures/rustc_use_parallel_compiler',
'rustc_interface/rustc_use_parallel_compiler', 'rustc_interface/rustc_use_parallel_compiler',

View File

@ -20,4 +20,5 @@ nightly = [
"dep:rustc_macros", "dep:rustc_macros",
"rustc_index_macros/nightly", "rustc_index_macros/nightly",
] ]
rustc_randomized_layouts = []
# tidy-alphabetical-end # tidy-alphabetical-end

View File

@ -33,8 +33,19 @@
/// ///
/// </div> /// </div>
#[macro_export] #[macro_export]
#[cfg(not(feature = "rustc_randomized_layouts"))]
macro_rules! static_assert_size { macro_rules! static_assert_size {
($ty:ty, $size:expr) => { ($ty:ty, $size:expr) => {
const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()]; const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()];
}; };
} }
#[macro_export]
#[cfg(feature = "rustc_randomized_layouts")]
macro_rules! static_assert_size {
($ty:ty, $size:expr) => {
// no effect other than using the statements.
// struct sizes are not deterministic under randomized layouts
const _: (usize, usize) = ($size, ::std::mem::size_of::<$ty>());
};
}

View File

@ -40,5 +40,6 @@ tracing = "0.1"
[features] [features]
# tidy-alphabetical-start # tidy-alphabetical-start
rustc_randomized_layouts = []
rustc_use_parallel_compiler = ["dep:rustc-rayon-core"] rustc_use_parallel_compiler = ["dep:rustc-rayon-core"]
# tidy-alphabetical-end # tidy-alphabetical-end

View File

@ -337,6 +337,7 @@ pub fn provided_to_erased<'tcx>(
// Ensure that values grow no larger than 64 bytes by accident. // Ensure that values grow no larger than 64 bytes by accident.
// Increase this limit if necessary, but do try to keep the size low if possible // Increase this limit if necessary, but do try to keep the size low if possible
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
#[cfg(not(feature = "rustc_randomized_layouts"))]
const _: () = { const _: () = {
if mem::size_of::<Value<'static>>() > 64 { if mem::size_of::<Value<'static>>() > 64 {
panic!("{}", concat!( panic!("{}", concat!(

View File

@ -35,6 +35,7 @@
use rustc_errors::{Diag, ErrorGuaranteed, StashKey}; use rustc_errors::{Diag, ErrorGuaranteed, StashKey};
use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
use rustc_hir::LangItem;
use rustc_index::IndexVec; use rustc_index::IndexVec;
use rustc_macros::{ use rustc_macros::{
extension, Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, extension, Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable,
@ -1570,8 +1571,15 @@ pub fn repr_options_of_def(self, did: LocalDefId) -> ReprOptions {
flags.insert(ReprFlags::RANDOMIZE_LAYOUT); flags.insert(ReprFlags::RANDOMIZE_LAYOUT);
} }
// box is special, on the one hand the compiler assumes an ordered layout, with the pointer
// always at offset zero. On the other hand we want scalar abi optimizations.
let is_box = self.is_lang_item(did.to_def_id(), LangItem::OwnedBox);
// This is here instead of layout because the choice must make it into metadata. // This is here instead of layout because the choice must make it into metadata.
if !self.consider_optimizing(|| format!("Reorder fields of {:?}", self.def_path_str(did))) { if is_box
|| !self
.consider_optimizing(|| format!("Reorder fields of {:?}", self.def_path_str(did)))
{
flags.insert(ReprFlags::IS_LINEAR); flags.insert(ReprFlags::IS_LINEAR);
} }

View File

@ -519,6 +519,9 @@
# are disabled statically" because `max_level_info` is enabled, set this value to `true`. # are disabled statically" because `max_level_info` is enabled, set this value to `true`.
#debug-logging = rust.debug-assertions (boolean) #debug-logging = rust.debug-assertions (boolean)
# Whether or not to build rustc, tools and the libraries with randomized type layout
#randomize-layout = false
# Whether or not overflow checks are enabled for the compiler and standard # Whether or not overflow checks are enabled for the compiler and standard
# library. # library.
# #

View File

@ -52,4 +52,5 @@ check-cfg = [
'cfg(no_global_oom_handling)', 'cfg(no_global_oom_handling)',
'cfg(no_rc)', 'cfg(no_rc)',
'cfg(no_sync)', 'cfg(no_sync)',
'cfg(randomized_layouts)',
] ]

View File

@ -90,7 +90,7 @@ fn test_partial_eq() {
#[test] #[test]
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
#[cfg_attr(miri, ignore)] // We'd like to run Miri with layout randomization #[cfg_attr(any(miri, randomized_layouts), ignore)] // We'd like to run Miri with layout randomization
fn test_sizes() { fn test_sizes() {
assert_eq!(core::mem::size_of::<LeafNode<(), ()>>(), 16); assert_eq!(core::mem::size_of::<LeafNode<(), ()>>(), 16);
assert_eq!(core::mem::size_of::<LeafNode<i64, i64>>(), 16 + CAPACITY * 2 * 8); assert_eq!(core::mem::size_of::<LeafNode<i64, i64>>(), 16 + CAPACITY * 2 * 8);

View File

@ -1810,6 +1810,9 @@ fn run(self, builder: &Builder<'_>) {
if builder.config.rust_optimize_tests { if builder.config.rust_optimize_tests {
cmd.arg("--optimize-tests"); cmd.arg("--optimize-tests");
} }
if builder.config.rust_randomize_layout {
cmd.arg("--rust-randomized-layout");
}
if builder.config.cmd.only_modified() { if builder.config.cmd.only_modified() {
cmd.arg("--only-modified"); cmd.arg("--only-modified");
} }

View File

@ -1618,6 +1618,15 @@ fn cargo(
rustflags.arg("-Csymbol-mangling-version=legacy"); rustflags.arg("-Csymbol-mangling-version=legacy");
} }
// FIXME: the following components don't build with `-Zrandomize-layout` yet:
// - wasm-component-ld, due to the `wast`crate
// - rust-analyzer, due to the rowan crate
// so we exclude entire categories of steps here due to lack of fine-grained control over
// rustflags.
if self.config.rust_randomize_layout && mode != Mode::ToolStd && mode != Mode::ToolRustc {
rustflags.arg("-Zrandomize-layout");
}
// Enable compile-time checking of `cfg` names, values and Cargo `features`. // Enable compile-time checking of `cfg` names, values and Cargo `features`.
// //
// Note: `std`, `alloc` and `core` imports some dependencies by #[path] (like // Note: `std`, `alloc` and `core` imports some dependencies by #[path] (like
@ -2193,6 +2202,9 @@ fn cargo(
rustflags.arg("-Zvalidate-mir"); rustflags.arg("-Zvalidate-mir");
rustflags.arg(&format!("-Zmir-opt-level={mir_opt_level}")); rustflags.arg(&format!("-Zmir-opt-level={mir_opt_level}"));
} }
if self.config.rust_randomize_layout {
rustflags.arg("--cfg=randomized_layouts");
}
// Always enable inlining MIR when building the standard library. // Always enable inlining MIR when building the standard library.
// Without this flag, MIR inlining is disabled when incremental compilation is enabled. // Without this flag, MIR inlining is disabled when incremental compilation is enabled.
// That causes some mir-opt tests which inline functions from the standard library to // That causes some mir-opt tests which inline functions from the standard library to

View File

@ -280,6 +280,7 @@ pub struct Config {
pub rust_codegen_backends: Vec<String>, pub rust_codegen_backends: Vec<String>,
pub rust_verify_llvm_ir: bool, pub rust_verify_llvm_ir: bool,
pub rust_thin_lto_import_instr_limit: Option<u32>, pub rust_thin_lto_import_instr_limit: Option<u32>,
pub rust_randomize_layout: bool,
pub rust_remap_debuginfo: bool, pub rust_remap_debuginfo: bool,
pub rust_new_symbol_mangling: Option<bool>, pub rust_new_symbol_mangling: Option<bool>,
pub rust_profile_use: Option<String>, pub rust_profile_use: Option<String>,
@ -1090,6 +1091,7 @@ struct Rust {
codegen_units: Option<u32> = "codegen-units", codegen_units: Option<u32> = "codegen-units",
codegen_units_std: Option<u32> = "codegen-units-std", codegen_units_std: Option<u32> = "codegen-units-std",
debug_assertions: Option<bool> = "debug-assertions", debug_assertions: Option<bool> = "debug-assertions",
randomize_layout: Option<bool> = "randomize-layout",
debug_assertions_std: Option<bool> = "debug-assertions-std", debug_assertions_std: Option<bool> = "debug-assertions-std",
overflow_checks: Option<bool> = "overflow-checks", overflow_checks: Option<bool> = "overflow-checks",
overflow_checks_std: Option<bool> = "overflow-checks-std", overflow_checks_std: Option<bool> = "overflow-checks-std",
@ -1181,6 +1183,7 @@ pub fn default_opts() -> Config {
backtrace: true, backtrace: true,
rust_optimize: RustOptimize::Bool(true), rust_optimize: RustOptimize::Bool(true),
rust_optimize_tests: true, rust_optimize_tests: true,
rust_randomize_layout: false,
submodules: None, submodules: None,
docs: true, docs: true,
docs_minification: true, docs_minification: true,
@ -1640,6 +1643,7 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
backtrace, backtrace,
incremental, incremental,
parallel_compiler, parallel_compiler,
randomize_layout,
default_linker, default_linker,
channel, channel,
description, description,
@ -1729,6 +1733,7 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
set(&mut config.lld_mode, lld_mode); set(&mut config.lld_mode, lld_mode);
set(&mut config.llvm_bitcode_linker_enabled, llvm_bitcode_linker); set(&mut config.llvm_bitcode_linker_enabled, llvm_bitcode_linker);
config.rust_randomize_layout = randomize_layout.unwrap_or_default();
config.llvm_tools_enabled = llvm_tools.unwrap_or(true); config.llvm_tools_enabled = llvm_tools.unwrap_or(true);
config.rustc_parallel = config.rustc_parallel =
parallel_compiler.unwrap_or(config.channel == "dev" || config.channel == "nightly"); parallel_compiler.unwrap_or(config.channel == "dev" || config.channel == "nightly");
@ -2900,6 +2905,7 @@ macro_rules! warn {
let Rust { let Rust {
// Following options are the CI rustc incompatible ones. // Following options are the CI rustc incompatible ones.
optimize, optimize,
randomize_layout,
debug_logging, debug_logging,
debuginfo_level_rustc, debuginfo_level_rustc,
llvm_tools, llvm_tools,
@ -2964,6 +2970,7 @@ macro_rules! warn {
// otherwise, we just print a warning with `warn` macro. // otherwise, we just print a warning with `warn` macro.
err!(current_rust_config.optimize, optimize); err!(current_rust_config.optimize, optimize);
err!(current_rust_config.randomize_layout, randomize_layout);
err!(current_rust_config.debug_logging, debug_logging); err!(current_rust_config.debug_logging, debug_logging);
err!(current_rust_config.debuginfo_level_rustc, debuginfo_level_rustc); err!(current_rust_config.debuginfo_level_rustc, debuginfo_level_rustc);
err!(current_rust_config.rpath, rpath); err!(current_rust_config.rpath, rpath);

View File

@ -678,6 +678,9 @@ fn rustc_features(&self, kind: Kind, target: TargetSelection) -> String {
if self.config.rustc_parallel { if self.config.rustc_parallel {
features.push("rustc_use_parallel_compiler"); features.push("rustc_use_parallel_compiler");
} }
if self.config.rust_randomize_layout {
features.push("rustc_randomized_layouts");
}
// If debug logging is on, then we want the default for tracing: // If debug logging is on, then we want the default for tracing:
// https://github.com/tokio-rs/tracing/blob/3dd5c03d907afdf2c39444a29931833335171554/tracing/src/level_filters.rs#L26 // https://github.com/tokio-rs/tracing/blob/3dd5c03d907afdf2c39444a29931833335171554/tracing/src/level_filters.rs#L26

View File

@ -50,6 +50,7 @@ ENV RUST_CONFIGURE_ARGS \
--build=x86_64-unknown-linux-gnu \ --build=x86_64-unknown-linux-gnu \
--llvm-root=/usr/lib/llvm-17 \ --llvm-root=/usr/lib/llvm-17 \
--enable-llvm-link-shared \ --enable-llvm-link-shared \
--set rust.randomize-layout=true \
--set rust.thin-lto-import-instr-limit=10 --set rust.thin-lto-import-instr-limit=10
COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/ COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/

View File

@ -136,6 +136,7 @@
"min-llvm-version", "min-llvm-version",
"min-system-llvm-version", "min-system-llvm-version",
"needs-asm-support", "needs-asm-support",
"needs-deterministic-layouts",
"needs-dlltool", "needs-dlltool",
"needs-dynamic-linking", "needs-dynamic-linking",
"needs-force-clang-based-tests", "needs-force-clang-based-tests",

View File

@ -274,6 +274,9 @@ pub struct Config {
/// Flags to pass to the compiler when building for the target /// Flags to pass to the compiler when building for the target
pub target_rustcflags: Vec<String>, pub target_rustcflags: Vec<String>,
/// Whether the compiler and stdlib has been built with randomized struct layouts
pub rust_randomized_layout: bool,
/// Whether tests should be optimized by default. Individual test-suites and test files may /// Whether tests should be optimized by default. Individual test-suites and test files may
/// override this setting. /// override this setting.
pub optimize_tests: bool, pub optimize_tests: bool,

View File

@ -134,6 +134,11 @@ pub(super) fn handle_needs(
condition: config.target_cfg().relocation_model == "pic", condition: config.target_cfg().relocation_model == "pic",
ignore_reason: "ignored on targets without PIC relocation model", ignore_reason: "ignored on targets without PIC relocation model",
}, },
Need {
name: "needs-deterministic-layouts",
condition: !config.rust_randomized_layout,
ignore_reason: "ignored when randomizing layouts",
},
Need { Need {
name: "needs-wasmtime", name: "needs-wasmtime",
condition: config.runner.as_ref().is_some_and(|r| r.contains("wasmtime")), condition: config.runner.as_ref().is_some_and(|r| r.contains("wasmtime")),

View File

@ -99,6 +99,11 @@ pub fn parse_config(args: Vec<String>) -> Config {
) )
.optmulti("", "host-rustcflags", "flags to pass to rustc for host", "FLAGS") .optmulti("", "host-rustcflags", "flags to pass to rustc for host", "FLAGS")
.optmulti("", "target-rustcflags", "flags to pass to rustc for target", "FLAGS") .optmulti("", "target-rustcflags", "flags to pass to rustc for target", "FLAGS")
.optflag(
"",
"rust-randomized-layout",
"set this when rustc/stdlib were compiled with randomized layouts",
)
.optflag("", "optimize-tests", "run tests with optimizations enabled") .optflag("", "optimize-tests", "run tests with optimizations enabled")
.optflag("", "verbose", "run tests verbosely, showing all output") .optflag("", "verbose", "run tests verbosely, showing all output")
.optflag( .optflag(
@ -286,6 +291,7 @@ fn make_absolute(path: PathBuf) -> PathBuf {
host_rustcflags: matches.opt_strs("host-rustcflags"), host_rustcflags: matches.opt_strs("host-rustcflags"),
target_rustcflags: matches.opt_strs("target-rustcflags"), target_rustcflags: matches.opt_strs("target-rustcflags"),
optimize_tests: matches.opt_present("optimize-tests"), optimize_tests: matches.opt_present("optimize-tests"),
rust_randomized_layout: matches.opt_present("rust-randomized-layout"),
target, target,
host: opt_str2(matches.opt_str("host")), host: opt_str2(matches.opt_str("host")),
cdb, cdb,

View File

@ -1,5 +1,6 @@
//@ only-64bit llvm appears to use stores instead of memset on 32bit //@ only-64bit llvm appears to use stores instead of memset on 32bit
//@ compile-flags: -C opt-level=3 -Z merge-functions=disabled //@ compile-flags: -C opt-level=3 -Z merge-functions=disabled
//@ needs-deterministic-layouts
// The below two functions ensure that both `String::new()` and `"".to_string()` // The below two functions ensure that both `String::new()` and `"".to_string()`
// produce the identical code. // produce the identical code.

View File

@ -5,6 +5,7 @@
//@ compile-flags: -C no-prepopulate-passes -Zinline-mir=no //@ compile-flags: -C no-prepopulate-passes -Zinline-mir=no
//@ ignore-debug: precondition checks in ptr::read make them a bad candidate for MIR inlining //@ ignore-debug: precondition checks in ptr::read make them a bad candidate for MIR inlining
//@ needs-deterministic-layouts
#![crate_type = "lib"] #![crate_type = "lib"]

View File

@ -1,4 +1,5 @@
//@ compile-flags: -O //@ compile-flags: -O
//@ needs-deterministic-layouts
#![crate_type = "lib"] #![crate_type = "lib"]
#![feature(exact_size_is_empty)] #![feature(exact_size_is_empty)]

View File

@ -1,6 +1,7 @@
// Check that draining at the front or back doesn't copy memory. // Check that draining at the front or back doesn't copy memory.
//@ compile-flags: -O //@ compile-flags: -O
//@ needs-deterministic-layouts
//@ ignore-debug: FIXME: checks for call detect scoped noalias metadata //@ ignore-debug: FIXME: checks for call detect scoped noalias metadata
#![crate_type = "lib"] #![crate_type = "lib"]

View File

@ -1,3 +1,4 @@
//@needs-deterministic-layouts
// Verify that we do not ICE when printing an invalid constant. // Verify that we do not ICE when printing an invalid constant.
// EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR_FOR_EACH_BIT_WIDTH
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR_FOR_EACH_PANIC_STRATEGY

View File

@ -1,12 +1,15 @@
//@ check-pass //@ check-pass
//@ compile-flags: -Zhir-stats //@ compile-flags: -Zhir-stats
//@ only-x86_64 //@ only-x86_64
// layout randomization affects the hir stat output
//@ needs-deterministic-layouts
// Type layouts sometimes change. When that happens, until the next bootstrap // Type layouts sometimes change. When that happens, until the next bootstrap
// bump occurs, stage1 and stage2 will give different outputs for this test. // bump occurs, stage1 and stage2 will give different outputs for this test.
// Add an `ignore-stage1` comment marker to work around that problem during // Add an `ignore-stage1` comment marker to work around that problem during
// that time. // that time.
// The aim here is to include at least one of every different type of top-level // The aim here is to include at least one of every different type of top-level
// AST/HIR node reported by `-Zhir-stats`. // AST/HIR node reported by `-Zhir-stats`.

View File

@ -1,4 +1,5 @@
//@ run-pass //@ run-pass
//@ needs-deterministic-layouts
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![allow(dead_code)] #![allow(dead_code)]