diff --git a/compiler/rustc_codegen_gcc/src/gcc_util.rs b/compiler/rustc_codegen_gcc/src/gcc_util.rs index 330b5ff6828d5..aaf6983106e21 100644 --- a/compiler/rustc_codegen_gcc/src/gcc_util.rs +++ b/compiler/rustc_codegen_gcc/src/gcc_util.rs @@ -7,6 +7,7 @@ use rustc_target::spec::Arch; fn gcc_features_by_flags(sess: &Session, features: &mut Vec) { target_features::retpoline_features_by_flags(sess, features); + target_features::sls_features_by_flags(sess, features); // FIXME: LLVM also sets +reserve-x18 here under some conditions. } diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index fbb582fe86018..1172deeb2d00e 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -643,6 +643,7 @@ fn llvm_features_by_flags(sess: &Session, features: &mut Vec) { } target_features::retpoline_features_by_flags(sess, features); + target_features::sls_features_by_flags(sess, features); // -Zfixed-x18 if sess.opts.unstable_opts.fixed_x18 { diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index e9209657984e0..dd764efeb9a23 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -7,6 +7,7 @@ use rustc_middle::middle::codegen_fn_attrs::{TargetFeature, TargetFeatureKind}; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::Session; +use rustc_session::config::HardenSls; use rustc_session::lint::builtin::AARCH64_SOFTFLOAT_NEON; use rustc_session::parse::feature_err; use rustc_span::{Span, Symbol, sym}; @@ -298,12 +299,18 @@ pub fn cfg_target_feature<'a, const N: usize>( sess.dcx().emit_warn(unknown_feature); } Some((_, stability, _)) => { - if let Err(reason) = stability.toggle_allowed() { - sess.dcx().emit_warn(errors::ForbiddenCTargetFeature { + if let Stability::Forbidden { reason, hard_error } = stability { + let diag = errors::ForbiddenCTargetFeature { feature: base_feature, enabled: if enable { "enabled" } else { "disabled" }, reason, - }); + }; + + if *hard_error { + sess.dcx().emit_err(diag); + } else { + sess.dcx().emit_warn(diag); + } } else if stability.requires_nightly().is_some() { // An unstable feature. Warn about using it. It makes little sense // to hard-error here since we just warn about fully unknown @@ -449,6 +456,18 @@ pub fn retpoline_features_by_flags(sess: &Session, features: &mut Vec) { } } +pub fn sls_features_by_flags(sess: &Session, features: &mut Vec) { + match &sess.opts.unstable_opts.harden_sls { + HardenSls::None => (), + HardenSls::All => { + features.push("+harden-sls-ijmp".into()); + features.push("+harden-sls-ret".into()); + } + HardenSls::Return => features.push("+harden-sls-ret".into()), + HardenSls::IndirectJmp => features.push("+harden-sls-ijmp".into()), + } +} + pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { rust_target_features: |tcx, cnum| { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 5e2671ef4ef6b..ea592ed26a66b 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -3074,10 +3074,11 @@ pub(crate) mod dep_tracking { use super::{ AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CoverageOptions, CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn, - InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail, - LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, OutFileName, OutputType, - OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks, SourceFileHashAlgorithm, - SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, + HardenSls, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, + LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, + OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks, + SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, + WasiExecModel, }; use crate::lint; use crate::utils::NativeLib; @@ -3180,6 +3181,7 @@ pub(crate) mod dep_tracking { Polonius, InliningThreshold, FunctionReturn, + HardenSls, Align, ); @@ -3394,6 +3396,16 @@ pub enum FunctionReturn { ThunkExtern, } +/// The different settings that the `-Zharden-sls` flag can have. +#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)] +pub enum HardenSls { + #[default] + None, + All, + Return, + IndirectJmp, +} + /// Whether extra span comments are included when dumping MIR, via the `-Z mir-include-spans` flag. /// By default, only enabled in the NLL MIR dumps, and disabled in all other passes. #[derive(Clone, Copy, Default, PartialEq, Debug)] diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 9219b5a7e8aca..66701fb48db0e 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -878,6 +878,7 @@ mod desc { "either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number"; pub(crate) const parse_llvm_module_flag: &str = ":::. Type must currently be `u32`. Behavior should be one of (`error`, `warning`, `require`, `override`, `append`, `appendunique`, `max`, `min`)"; pub(crate) const parse_function_return: &str = "`keep` or `thunk-extern`"; + pub(crate) const parse_harden_sls: &str = "`none`, `all`, `return` or `indirect-jmp`"; pub(crate) const parse_wasm_c_abi: &str = "`spec`"; pub(crate) const parse_mir_include_spans: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or `nll` (default: `nll`)"; @@ -2029,6 +2030,17 @@ pub mod parse { true } + pub(crate) fn parse_harden_sls(slot: &mut HardenSls, v: Option<&str>) -> bool { + match v { + Some("none") => *slot = HardenSls::None, + Some("all") => *slot = HardenSls::All, + Some("return") => *slot = HardenSls::Return, + Some("indirect-jmp") => *slot = HardenSls::IndirectJmp, + _ => return false, + } + true + } + pub(crate) fn parse_wasm_c_abi(_slot: &mut (), v: Option<&str>) -> bool { v == Some("spec") } @@ -2374,6 +2386,9 @@ options! { graphviz_font: String = ("Courier, monospace".to_string(), parse_string, [UNTRACKED], "use the given `fontname` in graphviz output; can be overridden by setting \ environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)"), + harden_sls: HardenSls = (HardenSls::None, parse_harden_sls, [TRACKED TARGET_MODIFIER], + "flag to mitigate against straight line speculation (SLS) [none|all|return|indirect-jmp] \ + (default: none)"), has_thread_local: Option = (None, parse_opt_bool, [TRACKED], "explicitly enable the `cfg(target_thread_local)` directive"), help: bool = (false, parse_no_value, [UNTRACKED], "Print unstable compiler options"), diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index bc12e1eb97370..ac48cfb75db6a 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -28,7 +28,12 @@ pub enum Stability { /// set in the target spec. It is never set in `cfg(target_feature)`. Used in /// particular for features are actually ABI configuration flags (not all targets are as nice as /// RISC-V and have an explicit way to set the ABI separate from target features). - Forbidden { reason: &'static str }, + Forbidden { + reason: &'static str, + /// True if this is always an error, false if this can be reported as a warning when set via + /// `-Ctarget-feature`. + hard_error: bool, + }, } use Stability::*; @@ -41,8 +46,9 @@ impl HashStable for Stability { Stability::Unstable(nightly_feature) => { nightly_feature.hash_stable(hcx, hasher); } - Stability::Forbidden { reason } => { + Stability::Forbidden { reason, hard_error } => { reason.hash_stable(hcx, hasher); + hard_error.hash_stable(hcx, hasher); } } } @@ -73,12 +79,12 @@ impl Stability { } /// Returns whether the feature may be toggled via `#[target_feature]` or `-Ctarget-feature`. - /// (It might still be nightly-only even if this returns `true`, so make sure to also check + /// (It might still be nightly-only even if this returns `Ok(())`, so make sure to also check /// `requires_nightly`.) pub fn toggle_allowed(&self) -> Result<(), &'static str> { match self { Stability::Unstable(_) | Stability::Stable { .. } => Ok(()), - Stability::Forbidden { reason } => Err(reason), + Stability::Forbidden { reason, hard_error: _ } => Err(reason), } } } @@ -135,7 +141,10 @@ static ARM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("aes", Unstable(sym::arm_target_feature), &["neon"]), ( "atomics-32", - Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" }, + Stability::Forbidden { + reason: "unsound because it changes the ABI of atomic operations", + hard_error: false, + }, &[], ), ("crc", Unstable(sym::arm_target_feature), &[]), @@ -211,7 +220,11 @@ static AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ // FEAT_FLAGM2 ("flagm2", Unstable(sym::aarch64_unstable_target_feature), &[]), // We forbid directly toggling just `fp-armv8`; it must be toggled with `neon`. - ("fp-armv8", Stability::Forbidden { reason: "Rust ties `fp-armv8` to `neon`" }, &[]), + ( + "fp-armv8", + Stability::Forbidden { reason: "Rust ties `fp-armv8` to `neon`", hard_error: false }, + &[], + ), // FEAT_FP8 ("fp8", Unstable(sym::aarch64_unstable_target_feature), &["faminmax", "lut", "bf16"]), // FEAT_FP8DOT2 @@ -274,7 +287,11 @@ static AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("rcpc3", Unstable(sym::aarch64_unstable_target_feature), &["rcpc2"]), // FEAT_RDM ("rdm", Stable, &["neon"]), - ("reserve-x18", Forbidden { reason: "use `-Zfixed-x18` compiler flag instead" }, &[]), + ( + "reserve-x18", + Forbidden { reason: "use `-Zfixed-x18` compiler flag instead", hard_error: false }, + &[], + ), // FEAT_SB ("sb", Stable, &[]), // FEAT_SHA1 & FEAT_SHA256 @@ -436,6 +453,16 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("fma", Stable, &["avx"]), ("fxsr", Stable, &[]), ("gfni", Stable, &["sse2"]), + ( + "harden-sls-ijmp", + Stability::Forbidden { reason: "use `harden-sls` compiler flag instead", hard_error: true }, + &[], + ), + ( + "harden-sls-ret", + Stability::Forbidden { reason: "use `harden-sls` compiler flag instead", hard_error: true }, + &[], + ), ("kl", Stable, &["sse2"]), ("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]), ("lzcnt", Stable, &[]), @@ -448,17 +475,26 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("rdseed", Stable, &[]), ( "retpoline-external-thunk", - Stability::Forbidden { reason: "use `-Zretpoline-external-thunk` compiler flag instead" }, + Stability::Forbidden { + reason: "use `-Zretpoline-external-thunk` compiler flag instead", + hard_error: false, + }, &[], ), ( "retpoline-indirect-branches", - Stability::Forbidden { reason: "use `-Zretpoline` compiler flag instead" }, + Stability::Forbidden { + reason: "use `-Zretpoline` compiler flag instead", + hard_error: false, + }, &[], ), ( "retpoline-indirect-calls", - Stability::Forbidden { reason: "use `-Zretpoline` compiler flag instead" }, + Stability::Forbidden { + reason: "use `-Zretpoline` compiler flag instead", + hard_error: false, + }, &[], ), ("rtm", Unstable(sym::rtm_target_feature), &[]), @@ -466,7 +502,11 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("sha512", Stable, &["avx2"]), ("sm3", Stable, &["avx"]), ("sm4", Stable, &["avx2"]), - ("soft-float", Stability::Forbidden { reason: "use a soft-float target instead" }, &[]), + ( + "soft-float", + Stability::Forbidden { reason: "use a soft-float target instead", hard_error: false }, + &[], + ), ("sse", Stable, &[]), ("sse2", Stable, &["sse"]), ("sse3", Stable, &["sse2"]), @@ -608,7 +648,10 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("f", Unstable(sym::riscv_target_feature), &["zicsr"]), ( "forced-atomics", - Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" }, + Stability::Forbidden { + reason: "unsound because it changes the ABI of atomic operations", + hard_error: false, + }, &[], ), ("m", Stable, &[]), @@ -863,7 +906,7 @@ const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("miscellaneous-extensions-3", Stable, &[]), ("miscellaneous-extensions-4", Stable, &[]), ("nnp-assist", Stable, &["vector"]), - ("soft-float", Forbidden { reason: "currently unsupported ABI-configuration feature" }, &[]), + ("soft-float", Forbidden { reason: "currently unsupported ABI-configuration feature", hard_error: false }, &[]), ("transactional-execution", Unstable(sym::s390x_target_feature), &[]), ("vector", Stable, &[]), ("vector-enhancements-1", Stable, &["vector"]), diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index 08371a779e117..810ced0b85e67 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -241,12 +241,14 @@ See also [Debuginfo tests](compiletest.md#debuginfo-tests) for directives for ig | Directive | Explanation | Supported test suites | Possible values | |---------------------|----------------------------------------------------------------------------------------------|--------------------------------------------|--------------------------------------------------------------------------------------------| -| `compile-flags` | Flags passed to `rustc` when building the test or aux file | All except for `run-make`/`run-make-cargo` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental` or `--edition` | -| `edition` | The edition used to build the test | All except for `run-make`/`run-make-cargo` | Any valid `--edition` value | -| `rustc-env` | Env var to set when running `rustc` | All except for `run-make`/`run-make-cargo` | `=` | -| `unset-rustc-env` | Env var to unset when running `rustc` | All except for `run-make`/`run-make-cargo` | Any env var name | -| `incremental` | Proper incremental support for tests outside of incremental test suite | `ui`, `crashes` | N/A | -| `no-prefer-dynamic` | Don't use `-C prefer-dynamic`, don't build as a dylib via a `--crate-type=dylib` preset flag | `ui`, `crashes` | N/A | +| `compile-flags` | Flags passed to `rustc` when building the test or aux file | All except for `run-make`/`run-make-cargo` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental` or `--edition` | +| `minicore-compile-flags` | Additional flags passed to `rustc` when building minicore | All except for `run-make`/`run-make-cargo` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental` or `--edition` | +| `non-aux-compile-flags` | Additional flags passed to `rustc` when building the test (not for auxiliary builds) | All except for `run-make`/`run-make-cargo` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental` or `--edition` | +| `edition` | The edition used to build the test | All except for `run-make`/`run-make-cargo` | Any valid `--edition` value | +| `rustc-env` | Env var to set when running `rustc` | All except for `run-make`/`run-make-cargo` | `=` | +| `unset-rustc-env` | Env var to unset when running `rustc` | All except for `run-make`/`run-make-cargo` | Any env var name | +| `incremental` | Proper incremental support for tests outside of incremental test suite | `ui`, `crashes` | N/A | +| `no-prefer-dynamic` | Don't use `-C prefer-dynamic`, don't build as a dylib via a `--crate-type=dylib` preset flag | `ui`, `crashes` | N/A |
diff --git a/src/doc/rustc-dev-guide/src/tests/minicore.md b/src/doc/rustc-dev-guide/src/tests/minicore.md index 5d05c2c1e0a9a..ca68e55efc952 100644 --- a/src/doc/rustc-dev-guide/src/tests/minicore.md +++ b/src/doc/rustc-dev-guide/src/tests/minicore.md @@ -44,6 +44,11 @@ The `minicore` items must be kept up to date with `core`. For consistent diagnostic output between using `core` and `minicore`, any `diagnostic` attributes (e.g. `on_unimplemented`) should be replicated exactly in `minicore`. +## Specific compile flags +`compile-flags` is used both for auxiliary builds (including minicore) and main test build. +`minicore-compile-flags` directive may be used to provide compile flags for minicore build only. +`non-aux-compile-flags` directive may be used to provide compile flags for main test only. + ## Example codegen test that uses `minicore` ```rust,no_run diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index 462d9ae626b0a..44d9411649f64 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -206,6 +206,8 @@ pub(crate) struct TestProps { pub add_minicore: bool, /// Add these flags to the build of `minicore`. pub minicore_compile_flags: Vec, + /// Add these flags to the non-auxiliary build. + pub non_aux_compile_flags: Vec, /// Whether line annotations are required for the given error kind. pub dont_require_annotations: HashSet, /// Whether pretty printers should be disabled in gdb. @@ -259,6 +261,7 @@ mod directives { pub const NO_AUTO_CHECK_CFG: &'static str = "no-auto-check-cfg"; pub const ADD_MINICORE: &'static str = "add-minicore"; pub const MINICORE_COMPILE_FLAGS: &'static str = "minicore-compile-flags"; + pub const NON_AUX_COMPILE_FLAGS: &'static str = "non-aux-compile-flags"; pub const DISABLE_GDB_PRETTY_PRINTERS: &'static str = "disable-gdb-pretty-printers"; pub const COMPARE_OUTPUT_BY_LINES: &'static str = "compare-output-by-lines"; } @@ -316,6 +319,7 @@ impl TestProps { no_auto_check_cfg: false, add_minicore: false, minicore_compile_flags: vec![], + non_aux_compile_flags: vec![], dont_require_annotations: Default::default(), disable_gdb_pretty_printers: false, compare_output_by_lines: false, diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs index 9813ac7ff500d..718009b7eb325 100644 --- a/src/tools/compiletest/src/directives/directive_names.rs +++ b/src/tools/compiletest/src/directives/directive_names.rs @@ -196,6 +196,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "needs-xray", "no-auto-check-cfg", "no-prefer-dynamic", + "non-aux-compile-flags", "normalize-stderr", "normalize-stderr-32bit", "normalize-stderr-64bit", diff --git a/src/tools/compiletest/src/directives/handlers.rs b/src/tools/compiletest/src/directives/handlers.rs index b53bda90f626b..59c809997976b 100644 --- a/src/tools/compiletest/src/directives/handlers.rs +++ b/src/tools/compiletest/src/directives/handlers.rs @@ -339,6 +339,19 @@ fn make_directive_handlers_map() -> HashMap<&'static str, Handler> { props.minicore_compile_flags.extend(flags); } }), + handler(NON_AUX_COMPILE_FLAGS, |config, ln, props| { + if let Some(flags) = config.parse_name_value_directive(ln, NON_AUX_COMPILE_FLAGS) { + let flags = split_flags(&flags); + // FIXME(#147955): Extract and unify this with other handlers that + // check compiler flags, e.g. COMPILE_FLAGS. + for flag in &flags { + if flag == "--edition" || flag.starts_with("--edition=") { + panic!("you must use `//@ edition` to configure the edition"); + } + } + props.non_aux_compile_flags.extend(flags); + } + }), handler(DONT_REQUIRE_ANNOTATIONS, |config, ln, props| { if let Some(err_kind) = config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS) { diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index e6eb1f3bd957f..3514e47f203b8 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1004,6 +1004,7 @@ impl<'test> TestCx<'test> { allow_unused, LinkToAux::Yes, passes, + false, ); self.compose_and_run_compiler(rustc, None) @@ -1364,6 +1365,7 @@ impl<'test> TestCx<'test> { AllowUnused::Yes, LinkToAux::No, vec![], + true, ); rustc.args(&["--crate-type", "rlib"]); @@ -1423,6 +1425,7 @@ impl<'test> TestCx<'test> { AllowUnused::No, LinkToAux::No, Vec::new(), + false, ); aux_cx.build_all_auxiliary(&aux_dir, &mut aux_rustc); @@ -1608,6 +1611,7 @@ impl<'test> TestCx<'test> { allow_unused: AllowUnused, link_to_aux: LinkToAux, passes: Vec, // Vec of passes under mir-opt test to be dumped + for_minicore: bool, ) -> Command { // FIXME(Zalathar): We should have a cleaner distinction between // `rustc` flags, `rustdoc` flags, and flags shared by both. @@ -1956,6 +1960,10 @@ impl<'test> TestCx<'test> { } compiler.args(&self.props.compile_flags); + let is_aux = input_file.components().map(|c| c.as_os_str()).any(|c| c == "auxiliary"); + if !for_minicore && !is_aux { + compiler.args(&self.props.non_aux_compile_flags); + } compiler } @@ -2177,6 +2185,7 @@ impl<'test> TestCx<'test> { AllowUnused::No, LinkToAux::Yes, Vec::new(), + false, ); let proc_res = self.compose_and_run_compiler(rustc, None); diff --git a/src/tools/compiletest/src/runtest/assembly.rs b/src/tools/compiletest/src/runtest/assembly.rs index 18027328abfe0..a2770c475d73e 100644 --- a/src/tools/compiletest/src/runtest/assembly.rs +++ b/src/tools/compiletest/src/runtest/assembly.rs @@ -42,6 +42,7 @@ impl TestCx<'_> { AllowUnused::No, LinkToAux::Yes, Vec::new(), + false, ); let proc_res = self.compose_and_run_compiler(rustc, None); diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs index 31b80d0924da4..768b840621ada 100644 --- a/src/tools/compiletest/src/runtest/ui.rs +++ b/src/tools/compiletest/src/runtest/ui.rs @@ -234,6 +234,7 @@ impl TestCx<'_> { AllowUnused::No, LinkToAux::Yes, Vec::new(), + false, ); // If a test is revisioned, it's fixed source file can be named "a.foo.fixed", which, diff --git a/tests/assembly-llvm/x86_64-sls.rs b/tests/assembly-llvm/x86_64-sls.rs new file mode 100644 index 0000000000000..2a24e2116aa9a --- /dev/null +++ b/tests/assembly-llvm/x86_64-sls.rs @@ -0,0 +1,76 @@ +// Test harden-sls flag + +#![feature(core_intrinsics)] +//@ revisions: NONE ALL RET IJMP +//@ assembly-output: emit-asm +//@ compile-flags: -Copt-level=3 -Cunsafe-allow-abi-mismatch=harden-sls +//@ [NONE] compile-flags: -Zharden-sls=none +//@ [ALL] compile-flags: -Zharden-sls=all +//@ [RET] compile-flags: -Zharden-sls=return +//@ [IJMP] compile-flags: -Zharden-sls=indirect-jmp +//@ only-x86_64 +#![crate_type = "lib"] + +#[no_mangle] +pub fn double_return(a: i32, b: i32) -> i32 { + // CHECK-LABEL: double_return: + // CHECK: jle + // CHECK-NOT: int3 + // CHECK: retq + // RET-NEXT: int3 + // ALL-NEXT: int3 + // IJMP-NOT: int3 + // NONE-NOT: int3 + // CHECK: retq + // RET-NEXT: int3 + // ALL-NEXT: int3 + // IJMP-NOT: int3 + // NONE-NOT: int3 + if a > 0 { + unsafe { std::intrinsics::unchecked_div(a, b) } + } else { + unsafe { std::intrinsics::unchecked_div(b, a) } + } +} + +#[no_mangle] +pub fn indirect_branch(a: i32, b: i32, i: i32) -> i32 { + // CHECK-LABEL: indirect_branch: + // CHECK: jmpq * + // RET-NOT: int3 + // NONE-NOT: int3 + // IJMP-NEXT: int3 + // ALL-NEXT: int3 + // CHECK: retq + // RET-NEXT: int3 + // ALL-NEXT: int3 + // IJMP-NOT: int3 + // NONE-NOT: int3 + // CHECK: retq + // RET-NEXT: int3 + // ALL-NEXT: int3 + // IJMP-NOT: int3 + // NONE-NOT: int3 + match i { + 0 => unsafe { std::intrinsics::unchecked_div(a, b) }, + 1 => unsafe { std::intrinsics::unchecked_div(b, a) }, + 2 => unsafe { std::intrinsics::unchecked_div(b, a) + 2 }, + 3 => unsafe { std::intrinsics::unchecked_div(b, a) + 3 }, + 4 => unsafe { std::intrinsics::unchecked_div(b, a) + 4 }, + 5 => unsafe { std::intrinsics::unchecked_div(b, a) + 5 }, + 6 => unsafe { std::intrinsics::unchecked_div(b, a) + 6 }, + _ => panic!(""), + } +} + +#[no_mangle] +pub fn bar(ptr: fn()) { + // CHECK-LABEL: bar: + // CHECK: jmpq * + // RET-NOT: int3 + // NONE-NOT: int3 + // IJMP-NEXT: int3 + // ALL-NEXT: int3 + // CHECK-NOT: ret + ptr() +} diff --git a/tests/codegen-llvm/harden-sls.rs b/tests/codegen-llvm/harden-sls.rs new file mode 100644 index 0000000000000..76c4bf63d0e43 --- /dev/null +++ b/tests/codegen-llvm/harden-sls.rs @@ -0,0 +1,35 @@ +// ignore-tidy-linelength +// Test that the `harden-sls-ijmp`, `harden-sls-ret` target features is (not) emitted when +// the `harden-sls=[none|all|ret|indirect-jmp]` flag is (not) set. + +//@ add-minicore +//@ revisions: unset all ret indirect_jmp +//@ needs-llvm-components: x86 +//@ compile-flags: --target x86_64-unknown-linux-gnu +//@ [unset] compile-flags: -Zharden-sls=none +//@ [all] compile-flags: -Zharden-sls=all +//@ [ret] compile-flags: -Zharden-sls=return +//@ [indirect_jmp] compile-flags: -Zharden-sls=indirect-jmp + +#![crate_type = "lib"] +#![feature(no_core)] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[no_mangle] +pub fn foo() { + // CHECK: @foo() unnamed_addr #0 + + // unset-NOT: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+harden-sls-ijmp{{.*}} } + // unset-NOT: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+harden-sls-ret{{.*}} } + + // all: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+harden-sls-ijmp,+harden-sls-ret{{.*}} } + + // ret-NOT: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+harden-sls-ijmp{{.*}} } + // ret: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+harden-sls-ret{{.*}} } + + // indirect_jmp-NOT: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+harden-sls-ret{{.*}} } + // indirect_jmp: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+harden-sls-ijmp{{.*}} } +} diff --git a/tests/ui/target-feature/harden-sls-target-feature-flag.by_feature.stderr b/tests/ui/target-feature/harden-sls-target-feature-flag.by_feature.stderr new file mode 100644 index 0000000000000..cf410758e5c8a --- /dev/null +++ b/tests/ui/target-feature/harden-sls-target-feature-flag.by_feature.stderr @@ -0,0 +1,12 @@ +error: target feature `harden-sls-ijmp` cannot be enabled with `-Ctarget-feature`: use `harden-sls` compiler flag instead + | + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 + +error: target feature `harden-sls-ret` cannot be enabled with `-Ctarget-feature`: use `harden-sls` compiler flag instead + | + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 + +error: aborting due to 2 previous errors + diff --git a/tests/ui/target-feature/harden-sls-target-feature-flag.rs b/tests/ui/target-feature/harden-sls-target-feature-flag.rs new file mode 100644 index 0000000000000..a4512540e2e4a --- /dev/null +++ b/tests/ui/target-feature/harden-sls-target-feature-flag.rs @@ -0,0 +1,16 @@ +//@ add-minicore +//@ revisions: by_flag by_feature +//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib +//@ needs-llvm-components: x86 +//@ [by_flag]non-aux-compile-flags: -Zharden-sls=all +//@ [by_feature]non-aux-compile-flags: -Ctarget-feature=+harden-sls-ijmp,+harden-sls-ret +//@ [by_flag]build-pass +//@ [by_feature]check-fail +//@ ignore-backends: gcc +#![allow(non_camel_case_types)] +#![feature(no_core, lang_items)] +#![no_std] +#![no_core] + +//[by_feature]~? ERROR target feature `harden-sls-ijmp` cannot be enabled with `-Ctarget-feature`: use `harden-sls` compiler flag instead +//[by_feature]~? ERROR target feature `harden-sls-ret` cannot be enabled with `-Ctarget-feature`: use `harden-sls` compiler flag instead