From cb003984afb8788ffdfdab1decc191638f7fc063 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Mon, 8 Sep 2025 16:47:37 +0000 Subject: [PATCH] Stabilize `-Zstack-protector` as `-Cstack-protector` I propose stabilizing `-Cstack-protector` as `-Zstack-protector`. This PR adds a new `-Cstack-protector` flag, leaving the unstable `-Z` flag as is to ease the transition period. The `-Z` flag will be removed in the future. No RFC/MCP, this flag was added in 84197 and was not deemed large enough to require additional process. The tracking issue for this feature is 114903. The `-Cstack-protector=strong` mode uses the same underlying heuristics as Clang's `-fstack-protector-strong`. These heuristics weren't designed for Rust, and may be over-conservative in some cases - for example, if Rust stores a field's data in an alloca using an LLVM array type, LLVM regard the alloca as meaning that the function has a C array, and enable stack overflow canaries even if the function accesses the alloca in a safe way. Some people thought we should wait on stabilization until there are better heuristics, but I didn't hear about any concrete case where this unduly harms performance, and I think that when a need comes, we can improve the heuristics in LLVM after stabilization. The heuristics do seem to not be under-conservative, so this should not be a security risk. The `-Cstack-protector=basic` mode (`-fstack-protector`) uses heuristics that are specifically designed to catch old-C-style string manipulation. This is not a good fit to Rust, which does not perform much unsafe C-style string manipulation. As far as I can tell, nobody has been asking for it, and few people are using it even in today's C - modern distros (e.g. [Debian]) tend to use `-fstack-protector-strong`. Therefore, `-Cstack-protector=basic` has been **removed**. If anyone is interested in it, they are welcome to add it back as an unstable option. [Debian]: https://wiki.debian.org/Hardening#DEB_BUILD_HARDENING_STACKPROTECTOR_.28gcc.2Fg.2B-.2B-_-fstack-protector-strong.29 Most implementation was done in . The command-line attribute enables the relevant LLVM attribute on all functions in . Each target can indicate that it does not support stack canaries - currently, the GPU platforms `nvptx64-nvidia-cuda` and `amdgcn-amd-amdhsa`. On these platforms, use of `-Cstack-protector` causes an error. The feature has tests that make sure that the LLVM heuristic gives reasonable results for several functions, by checking for `__security_check_cookie` (on Windows) or `__stack_chk_fail` (on Linux). See No call-for-testing has been conducted, but the feature seems to be in use. No reported bugs seem to exist. - bbjornse was the original implementor at 84197 - mrcnski documented it at 111722 - wesleywiser added tests for Windows at 116037 - davidtwco worked on the feature at 121742 - nikic provided support from the LLVM side (on Zulip on and elsewhere), thanks nikic! No FIXMEs related to this feature. This feature cannot cause undefined behavior. No changes to reference/spec, docs added to the codegen docs as part of the stabilization PR. No. None. No support needed for rustdoc, clippy, rust-analyzer, rustfmt or rustup. Cargo could expose this as an option in build profiles but I would expect the decision as to what version should be used would be made for the entire crate graph at build time rather than by individual package authors. `-C stack-protector` is propagated to C compilers using cc-rs via rust-lang/cc-rs issue 1550 --- bootstrap.example.toml | 5 +-- compiler/rustc_codegen_llvm/src/attributes.rs | 1 - compiler/rustc_codegen_llvm/src/lib.rs | 25 +++++++------ compiler/rustc_interface/src/tests.rs | 3 +- compiler/rustc_session/src/errors.rs | 2 +- compiler/rustc_session/src/options.rs | 17 ++++++--- .../src/options/mitigation_coverage.rs | 4 -- compiler/rustc_session/src/session.rs | 17 +++++---- compiler/rustc_target/src/spec/mod.rs | 6 --- src/bootstrap/src/core/builder/cargo.rs | 2 +- src/doc/rustc/src/codegen-options/index.md | 37 +++++++++++++++++++ src/doc/rustc/src/exploit-mitigations.md | 2 +- ...otector-heuristics-effect-windows-32bit.rs | 35 ++++++------------ ...otector-heuristics-effect-windows-64bit.rs | 35 ++++++------------ .../stack-protector-heuristics-effect.rs | 33 +++++------------ .../stack-protector-target-support.rs | 14 +++---- tests/codegen-llvm/stack-protector.rs | 32 +++++++++++----- tests/ui/README.md | 2 +- tests/ui/abi/stack-protector.rs | 2 +- ...l-stack-protector-unsupported.all-z.stderr | 4 ++ ...ail-stack-protector-unsupported.all.stderr | 4 ++ .../fail-stack-protector-unsupported.rs | 31 ++++++++++++++++ ...-stack-protector-unsupported.strong.stderr | 4 ++ .../no-stack-protector-basic.rs | 9 +++++ .../no-stack-protector-basic.stable.stderr | 2 + .../no-stack-protector-basic.unstable.stderr | 2 + ...arn-stack-protector-unsupported.all.stderr | 4 -- ...n-stack-protector-unsupported.basic.stderr | 4 -- .../warn-stack-protector-unsupported.rs | 31 ---------------- ...-stack-protector-unsupported.strong.stderr | 4 -- 30 files changed, 195 insertions(+), 178 deletions(-) create mode 100644 tests/ui/stack-protector/fail-stack-protector-unsupported.all-z.stderr create mode 100644 tests/ui/stack-protector/fail-stack-protector-unsupported.all.stderr create mode 100644 tests/ui/stack-protector/fail-stack-protector-unsupported.rs create mode 100644 tests/ui/stack-protector/fail-stack-protector-unsupported.strong.stderr create mode 100644 tests/ui/stack-protector/no-stack-protector-basic.rs create mode 100644 tests/ui/stack-protector/no-stack-protector-basic.stable.stderr create mode 100644 tests/ui/stack-protector/no-stack-protector-basic.unstable.stderr delete mode 100644 tests/ui/stack-protector/warn-stack-protector-unsupported.all.stderr delete mode 100644 tests/ui/stack-protector/warn-stack-protector-unsupported.basic.stderr delete mode 100644 tests/ui/stack-protector/warn-stack-protector-unsupported.rs delete mode 100644 tests/ui/stack-protector/warn-stack-protector-unsupported.strong.stderr diff --git a/bootstrap.example.toml b/bootstrap.example.toml index 25e2ca5948bfb..bd780c2b1a9fe 100644 --- a/bootstrap.example.toml +++ b/bootstrap.example.toml @@ -760,10 +760,9 @@ #rust.frame-pointers = false # Indicates whether stack protectors should be used -# via the unstable option `-Zstack-protector`. +# via `-Cstack-protector`. # -# Valid options are : `none`(default),`basic`,`strong`, or `all`. -# `strong` and `basic` options may be buggy and are not recommended, see rust-lang/rust#114903. +# Valid options are : `none`(default), `strong`, or `all`. #rust.stack-protector = "none" # Prints each test name as it is executed, to help debug issues in the test harness itself. diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 1f59d250e08a0..441be406c40fd 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -297,7 +297,6 @@ fn stackprotector_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll A StackProtector::None => return None, StackProtector::All => AttributeKind::StackProtectReq, StackProtector::Strong => AttributeKind::StackProtectStrong, - StackProtector::Basic => AttributeKind::StackProtect, }; Some(sspattr.create_attr(cx.llcx)) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 65c70c754918d..944757c962638 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -279,18 +279,19 @@ impl CodegenBackend for LlvmCodegenBackend { Generate stack canaries in all functions. strong - Generate stack canaries in a function if it either: - - has a local variable of `[T; N]` type, regardless of `T` and `N` - - takes the address of a local variable. - - (Note that a local variable being borrowed is not equivalent to its - address being taken: e.g. some borrows may be removed by optimization, - while by-value argument passing may be implemented with reference to a - local stack variable in the ABI.) - - basic - Generate stack canaries in functions with local variables of `[T; N]` - type, where `T` is byte-sized and `N` >= 8. + Generate stack canaries for all functions, unless the compiler + can prove these functions can't be the source of a stack + buffer overflow (even in the presence of undefined behavior). + + This provides similar security guarantees to Clang's + `-fstack-protector-strong`. + + The exact rules are unstable and subject to change, but + currently, it generates stack protectors for functions that, + *post-optimization*, contain LLVM allocas (which + include all stack allocations - including fixed-size + allocations - that are used in a way that is not completely + determined by static control flow). none Do not generate stack canaries. diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 417cde119c21f..af0ca064af31b 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -638,6 +638,7 @@ fn test_codegen_options_tracking_hash() { tracked!(relocation_model, Some(RelocModel::Pic)); tracked!(relro_level, Some(RelroLevel::Full)); tracked!(split_debuginfo, Some(SplitDebuginfo::Packed)); + tracked!(stack_protector, Some(StackProtector::All)); tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0)); tracked!(target_cpu, Some(String::from("abc"))); tracked!(target_feature, String::from("all the features, all of them")); @@ -868,7 +869,7 @@ fn test_unstable_options_tracking_hash() { tracked!(small_data_threshold, Some(16)); tracked!(split_lto_unit, Some(true)); tracked!(src_hash_algorithm, Some(SourceFileHashAlgorithm::Sha1)); - tracked!(stack_protector, StackProtector::All); + tracked!(stack_protector, Some(StackProtector::All)); tracked!(teach, true); tracked!(thinlto, Some(true)); tracked!(tiny_const_eval_limit, true); diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 295d9c3617778..a38d36f33c874 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -206,7 +206,7 @@ pub(crate) struct EmbedSourceRequiresDebugInfo; #[derive(Diagnostic)] #[diag( - "`-Z stack-protector={$stack_protector}` is not supported for target {$target_triple} and will be ignored" + "`-C stack-protector={$stack_protector}` is not supported for target {$target_triple} and will be ignored" )] pub(crate) struct StackProtectorNotSupportedForTarget<'a> { pub(crate) stack_protector: StackProtector, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 9fc6036b98b34..747c4427ab9cb 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -932,8 +932,7 @@ mod desc { pub(crate) const parse_polonius: &str = "either no value or `legacy` (the default), or `next`"; pub(crate) const parse_annotate_moves: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc.), or a size limit in bytes"; - pub(crate) const parse_stack_protector: &str = - "one of (`none` (default), `basic`, `strong`, or `all`)"; + pub(crate) const parse_stack_protector: &str = "one of (`none` (default), `strong`, or `all`)"; pub(crate) const parse_branch_protection: &str = "a `,` separated combination of `bti`, `gcs`, `pac-ret`, (optionally with `pc`, `b-key`, `leaf` if `pac-ret` is set)"; pub(crate) const parse_proc_macro_execution_strategy: &str = "one of supported execution strategies (`same-thread`, or `cross-thread`)"; @@ -1959,9 +1958,12 @@ pub mod parse { true } - pub(crate) fn parse_stack_protector(slot: &mut StackProtector, v: Option<&str>) -> bool { + pub(crate) fn parse_stack_protector( + slot: &mut Option, + v: Option<&str>, + ) -> bool { match v.and_then(|s| StackProtector::from_str(s).ok()) { - Some(ssp) => *slot = ssp, + Some(ssp) => *slot = Some(ssp), _ => return false, } true @@ -2269,6 +2271,9 @@ options! { #[rustc_lint_opt_deny_field_access("use `Session::split_debuginfo` instead of this field")] split_debuginfo: Option = (None, parse_split_debuginfo, [TRACKED], "how to handle split-debuginfo, a platform-specific option"), + #[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")] + stack_protector: Option = (None, parse_stack_protector, [TRACKED MITIGATION], + "control stack smashing protection strategy (`rustc --print stack-protector-strategies` for details)"), strip: Strip = (Strip::None, parse_strip, [UNTRACKED], "tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"), symbol_mangling_version: Option = (None, @@ -2760,8 +2765,8 @@ written to standard error output)"), src_hash_algorithm: Option = (None, parse_src_file_hash, [TRACKED], "hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"), #[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")] - stack_protector: StackProtector = (StackProtector::None, parse_stack_protector, [TRACKED MITIGATION], - "control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)"), + stack_protector: Option = (None, parse_stack_protector, [TRACKED MITIGATION], + "control stack smashing protection strategy (`rustc --print stack-protector-strategies` for details)"), staticlib_allow_rdylib_deps: bool = (false, parse_bool, [TRACKED], "allow staticlibs to have rust dylib dependencies"), staticlib_prefer_dynamic: bool = (false, parse_bool, [TRACKED], diff --git a/compiler/rustc_session/src/options/mitigation_coverage.rs b/compiler/rustc_session/src/options/mitigation_coverage.rs index f396392cd2638..9171f93e2d7d1 100644 --- a/compiler/rustc_session/src/options/mitigation_coverage.rs +++ b/compiler/rustc_session/src/options/mitigation_coverage.rs @@ -20,7 +20,6 @@ impl DeniedPartialMitigationLevel { pub fn level_str(&self) -> &'static str { match self { DeniedPartialMitigationLevel::StackProtector(StackProtector::All) => "=all", - DeniedPartialMitigationLevel::StackProtector(StackProtector::Basic) => "=basic", DeniedPartialMitigationLevel::StackProtector(StackProtector::Strong) => "=strong", // currently `=disabled` should not appear DeniedPartialMitigationLevel::Enabled(false) => "=disabled", @@ -36,9 +35,6 @@ impl std::fmt::Display for DeniedPartialMitigationLevel { DeniedPartialMitigationLevel::StackProtector(StackProtector::All) => { write!(f, "all") } - DeniedPartialMitigationLevel::StackProtector(StackProtector::Basic) => { - write!(f, "basic") - } DeniedPartialMitigationLevel::StackProtector(StackProtector::Strong) => { write!(f, "strong") } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index a9e7f1503b9ca..bb1eb8fa48aa7 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -748,11 +748,12 @@ impl Session { } pub fn stack_protector(&self) -> StackProtector { - if self.target.options.supports_stack_protector { - self.opts.unstable_opts.stack_protector - } else { - StackProtector::None - } + // -C stack-protector overwrites -Z stack-protector, default to StackProtector::None + self.opts + .cg + .stack_protector + .or(self.opts.unstable_opts.stack_protector) + .unwrap_or(StackProtector::None) } pub fn must_emit_unwind_tables(&self) -> bool { @@ -1262,10 +1263,10 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } } - if sess.opts.unstable_opts.stack_protector != StackProtector::None { + if sess.stack_protector() != StackProtector::None { if !sess.target.options.supports_stack_protector { - sess.dcx().emit_warn(errors::StackProtectorNotSupportedForTarget { - stack_protector: sess.opts.unstable_opts.stack_protector, + sess.dcx().emit_err(errors::StackProtectorNotSupportedForTarget { + stack_protector: sess.stack_protector(), target_triple: &sess.opts.target_triple, }); } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 768e43146a0c1..99617880db4aa 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1352,12 +1352,6 @@ crate::target_spec_enum! { /// Disable stack canary generation. None = "none", - /// On LLVM, mark all generated LLVM functions with the `ssp` attribute (see - /// llvm/docs/LangRef.rst). This triggers stack canary generation in - /// functions which contain an array of a byte-sized type with more than - /// eight elements. - Basic = "basic", - /// On LLVM, mark all generated LLVM functions with the `sspstrong` /// attribute (see llvm/docs/LangRef.rst). This triggers stack canary /// generation in functions which either contain an array, or which take diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index f785254d90dae..51c7e2534a53a 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -972,7 +972,7 @@ impl Builder<'_> { cargo.env(profile_var("STRIP"), self.config.rust_strip.to_string()); if let Some(stack_protector) = &self.config.rust_stack_protector { - rustflags.arg(&format!("-Zstack-protector={stack_protector}")); + rustflags.arg(&format!("-Cstack-protector={stack_protector}")); } let debuginfo_level = match mode { diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index f0f991ed0c909..3b94827d89ae5 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -695,6 +695,43 @@ Note that all three options are supported on Linux and Apple platforms, Attempting to use an unsupported option requires using the nightly channel with the `-Z unstable-options` flag. +## stack-protector + +The option `-C stack-protector` (currently also supported in the +old style `-Z stack-protector`) controls the generation of +stack-protector canaries. + +This flag controls stack smashing protection strategy. + +Supported values for this option are: +- `none` (default): Disable stack canary generation +- `strong`: Generate stack canaries in all functions, unless the compiler + can prove these functions can't be the source of a stack + buffer overflow (even in the presence of undefined behavior). + + This provides similar security guarantees to Clang's + `-fstack-protector-strong`. + + The exact rules are unstable and subject to change, but + currently, it generates stack protectors for functions that, + *post-optimization*, contain LLVM allocas (which + include all stack allocations - including fixed-size + allocations - that are used in a way that is not completely + determined by static control flow). + - `all`: Generate stack canaries in all functions + +rustc does not have a mode equivalent to Clang's (or GCC's) +plain `-fstack-protector` - `-fstack-protector` is an older heuristic +designed for C, that only protects functions that allocate a +`char buf[N];` buffer on the stack, making it prone to buffer overflows +from length miscalculations. This heuristic is poorly suited for Rust +code. Even in C codebases, `-fstack-protector-strong` is nowadays +preferred because plain `-fstack-protector` misses many stack +buffer overflows. + +Stack protectors are not supported on many GPU targets, use of stack +protectors on these targets is an error. + ## strip The option `-C strip=val` controls stripping of debuginfo and similar auxiliary diff --git a/src/doc/rustc/src/exploit-mitigations.md b/src/doc/rustc/src/exploit-mitigations.md index 41e5c93a1b7dc..2523cdeb3b099 100644 --- a/src/doc/rustc/src/exploit-mitigations.md +++ b/src/doc/rustc/src/exploit-mitigations.md @@ -62,7 +62,7 @@ equivalent. | Stack clashing protection | Yes | Yes | 1.20.0 (2017-08-31) | | Read-only relocations and immediate binding | Yes | Yes | 1.21.0 (2017-10-12) | | Heap corruption protection | Yes | Yes | 1.32.0 (2019-01-17) (via operating system default or specified allocator) | -| Stack smashing protection | Yes | No, `-Z stack-protector` | Nightly | +| Stack smashing protection | Yes | No, `-C stack-protector` | ??? | | Forward-edge control flow protection | Yes | No, `-Z sanitizer=cfi` | Nightly | | Backward-edge control flow protection (e.g., shadow and safe stack) | Yes | No, `-Z sanitizer=shadow-call-stack,safestack` | Nightly | diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs index d1b51068fce5a..36355952f7db1 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs @@ -1,12 +1,11 @@ -//@ revisions: all strong basic none missing +//@ revisions: all strong none missing //@ assembly-output: emit-asm //@ only-windows //@ only-msvc //@ ignore-64bit 64-bit table based SEH has slightly different behaviors than classic SEH -//@ [all] compile-flags: -Z stack-protector=all -//@ [strong] compile-flags: -Z stack-protector=strong -//@ [basic] compile-flags: -Z stack-protector=basic -//@ [none] compile-flags: -Z stack-protector=none +//@ [all] compile-flags: -C stack-protector=all +//@ [strong] compile-flags: -C stack-protector=strong +//@ [none] compile-flags: -C stack-protector=none //@ compile-flags: -C opt-level=2 -Z merge-functions=disabled -Cpanic=abort -Cdebuginfo=1 #![crate_type = "lib"] @@ -18,7 +17,6 @@ pub fn emptyfn() { // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -36,7 +34,6 @@ pub fn array_char(f: fn(*const char)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -54,7 +51,6 @@ pub fn array_u8_1(f: fn(*const u8)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -70,10 +66,10 @@ pub fn array_u8_small(f: fn(*const u8)) { f(&b as *const _); // Small arrays do not lead to stack protection by the 'basic' heuristic. + // (basic is not currently supported, leaving the test anyway). // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -88,10 +84,10 @@ pub fn array_u8_large(f: fn(*const u8)) { // Since `a` is a byte array with size greater than 8, the basic heuristic // will also protect this function. + // (basic is not currently supported, leaving the test anyway). // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -109,10 +105,10 @@ pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) { // Since `a` is a byte array in the LLVM output, the basic heuristic will // also protect this function. + // (basic is not currently supported, leaving the test anyway). // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -128,7 +124,7 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // This function takes the address of a local variable taken. Although this // address is never used as a way to refer to stack memory, the `strong` - // heuristic adds stack smash protection. This is also the case in C++: + // heuristic adds stack smashing protection. This is also the case in C++: // ``` // cat << EOF | clang++ -O2 -fstack-protector-strong -S -x c++ - -o - | grep stack_chk // #include @@ -138,10 +134,10 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // } // EOF // ``` + // (basic is not currently supported, leaving the test anyway). // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -159,7 +155,6 @@ pub fn local_string_addr_taken(f: fn(&String)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -185,12 +180,11 @@ pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32 // Even though the local variable conceptually has its address taken, as // it's passed by reference to the trait function, the use of the reference - // is easily inlined. There is therefore no stack smash protection even with + // is easily inlined. There is therefore no stack smashing protection even with // the `strong` heuristic. // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -229,7 +223,6 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -260,7 +253,6 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -302,7 +294,6 @@ pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) { // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -316,7 +307,6 @@ pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -330,7 +320,6 @@ pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -352,12 +341,10 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { // function and into `f()`, this is implemented with pass-by-reference // using a suitably constructed fat-pointer (as if the functions // accepted &[u8]). This function therefore doesn't need dynamic array - // alloca, and is therefore not protected by the `strong` or `basic` - // heuristics. + // alloca, and is therefore not protected by the `strong` heuristic. // all-NOT: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs index 56a6f08da5877..6a5cd9cfaffd1 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs @@ -1,12 +1,11 @@ -//@ revisions: all strong basic none missing +//@ revisions: all strong none missing //@ assembly-output: emit-asm //@ only-windows //@ only-msvc //@ ignore-32bit 64-bit table based SEH has slightly different behaviors than classic SEH -//@ [all] compile-flags: -Z stack-protector=all -//@ [strong] compile-flags: -Z stack-protector=strong -//@ [basic] compile-flags: -Z stack-protector=basic -//@ [none] compile-flags: -Z stack-protector=none +//@ [all] compile-flags: -C stack-protector=all +//@ [strong] compile-flags: -C stack-protector=strong +//@ [none] compile-flags: -C stack-protector=none //@ compile-flags: -C opt-level=2 -Z merge-functions=disabled -Cpanic=abort #![crate_type = "lib"] @@ -17,7 +16,6 @@ pub fn emptyfn() { // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -36,7 +34,6 @@ pub fn array_char(f: fn(*const char)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -55,7 +52,6 @@ pub fn array_u8_1(f: fn(*const u8)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -72,10 +68,10 @@ pub fn array_u8_small(f: fn(*const u8)) { f(&b as *const _); // Small arrays do not lead to stack protection by the 'basic' heuristic. + // (basic is not currently supported, leaving the test anyway). // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -91,10 +87,10 @@ pub fn array_u8_large(f: fn(*const u8)) { // Since `a` is a byte array with size greater than 8, the basic heuristic // will also protect this function. + // (basic is not currently supported, leaving the test anyway). // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -113,10 +109,10 @@ pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) { // Since `a` is a byte array in the LLVM output, the basic heuristic will // also protect this function. + // (basic is not currently supported, leaving the test anyway). // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -133,7 +129,7 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // This function takes the address of a local variable taken. Although this // address is never used as a way to refer to stack memory, the `strong` - // heuristic adds stack smash protection. This is also the case in C++: + // heuristic adds stack smashing protection. This is also the case in C++: // ``` // cat << EOF | clang++ -O2 -fstack-protector-strong -S -x c++ - -o - | grep stack_chk // #include @@ -146,7 +142,6 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -165,7 +160,6 @@ pub fn local_string_addr_taken(f: fn(&String)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -192,12 +186,11 @@ pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32 // Even though the local variable conceptually has its address taken, as // it's passed by reference to the trait function, the use of the reference - // is easily inlined. There is therefore no stack smash protection even with + // is easily inlined. There is therefore no stack smashing protection even with // the `strong` heuristic. // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -237,7 +230,6 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -269,7 +261,6 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -312,7 +303,6 @@ pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) { // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -327,7 +317,6 @@ pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -342,7 +331,6 @@ pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { // all: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie @@ -365,12 +353,11 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { // function and into `f()`, this is implemented with pass-by-reference // using a suitably constructed fat-pointer (as if the functions // accepted &[u8]). This function therefore doesn't need dynamic array - // alloca, and is therefore not protected by the `strong` or `basic` - // heuristics. + // alloca, and is therefore not protected by the `strong` heuristic. // all-NOT: __security_check_cookie // strong-NOT: __security_check_cookie - // basic-NOT: __security_check_cookie + // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect.rs index 3728ff3adf105..f508896d7eb97 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect.rs @@ -1,16 +1,15 @@ -//@ revisions: all strong basic none missing +//@ revisions: all strong none missing //@ assembly-output: emit-asm //@ ignore-apple slightly different policy on stack protection of arrays //@ ignore-msvc stack check code uses different function names //@ ignore-nvptx64 stack protector is not supported //@ ignore-wasm32-unknown-unknown -//@ [all] compile-flags: -Z stack-protector=all -//@ [strong] compile-flags: -Z stack-protector=strong -//@ [basic] compile-flags: -Z stack-protector=basic -//@ [none] compile-flags: -Z stack-protector=none +//@ [all] compile-flags: -C stack-protector=all +//@ [strong] compile-flags: -C stack-protector=strong +//@ [none] compile-flags: -C stack-protector=none //@ compile-flags: -C opt-level=2 -Z merge-functions=disabled -// NOTE: the heuristics for stack smash protection inappropriately rely on types in LLVM IR, +// NOTE: the heuristics for stack smashing protection inappropriately rely on types in LLVM IR, // despite those types having no semantic meaning. This means that the `basic` and `strong` // settings do not behave in a coherent way. This is a known issue in LLVM. // See comments on https://github.com/rust-lang/rust/issues/114903. @@ -24,7 +23,6 @@ pub fn emptyfn() { // all: __stack_chk_fail // strong-NOT: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -42,7 +40,6 @@ pub fn array_char(f: fn(*const char)) { // all: __stack_chk_fail // strong: __stack_chk_fail - // basic: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -58,7 +55,6 @@ pub fn array_u8_1(f: fn(*const u8)) { // all: __stack_chk_fail // strong: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -72,10 +68,10 @@ pub fn array_u8_small(f: fn(*const u8)) { f(&b as *const _); // Small arrays do not lead to stack protection by the 'basic' heuristic. + // (basic is not currently supported, leaving the test anyway). // all: __stack_chk_fail // strong: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -88,10 +84,10 @@ pub fn array_u8_large(f: fn(*const u8)) { // Since `a` is a byte array with size greater than 8, the basic heuristic // will also protect this function. + // (basic is not currently supported, leaving the test anyway). // all: __stack_chk_fail // strong: __stack_chk_fail - // basic: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -107,10 +103,10 @@ pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) { // Since `a` is a byte array in the LLVM output, the basic heuristic will // also protect this function. + // (basic is not currently supported, leaving the test anyway). // all: __stack_chk_fail // strong: __stack_chk_fail - // basic: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -124,7 +120,7 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // This function takes the address of a local variable taken. Although this // address is never used as a way to refer to stack memory, the `strong` - // heuristic adds stack smash protection. This is also the case in C++: + // heuristic adds stack smashing protection. This is also the case in C++: // ``` // cat << EOF | clang++ -O2 -fstack-protector-strong -S -x c++ - -o - | grep stack_chk // #include @@ -137,7 +133,6 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) { // all: __stack_chk_fail // strong: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -153,7 +148,6 @@ pub fn local_string_addr_taken(f: fn(&String)) { // all: __stack_chk_fail // strong: __stack_chk_fail - // basic: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -177,12 +171,11 @@ pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32 // Even though the local variable conceptually has its address taken, as // it's passed by reference to the trait function, the use of the reference - // is easily inlined. There is therefore no stack smash protection even with + // is easily inlined. There is therefore no stack smashing protection even with // the `strong` heuristic. // all: __stack_chk_fail // strong-NOT: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -219,7 +212,6 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) { // all: __stack_chk_fail // strong: __stack_chk_fail - // basic: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -248,7 +240,6 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // all: __stack_chk_fail // strong: __stack_chk_fail - // basic: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -288,7 +279,6 @@ pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) { // all: __stack_chk_fail // strong-NOT: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -300,7 +290,6 @@ pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) { // all: __stack_chk_fail // strong-NOT: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -312,7 +301,6 @@ pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) { // all: __stack_chk_fail // strong-NOT: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -339,7 +327,6 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) { // all: __stack_chk_fail // strong-NOT: __stack_chk_fail - // basic-NOT: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } diff --git a/tests/assembly-llvm/stack-protector/stack-protector-target-support.rs b/tests/assembly-llvm/stack-protector/stack-protector-target-support.rs index 9f182985d1573..71f4421b70830 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-target-support.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-target-support.rs @@ -1,10 +1,10 @@ -// Test that stack smash protection code is emitted for all tier1 and tier2 +// Test that stack smashing protection code is emitted for all tier1 and tier2 // targets, with the exception of nvptx64-nvidia-cuda // //@ add-minicore //@ revisions: r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 //@ revisions: r24 r25 r26 r27 r28 r29 r30 r31 r32 r33 r36 r37 r38 r39 r40 r41 r42 r43 r44 -//@ revisions: r45 r46 r47 r48 r49 r50 r51 r52 r53 r54 r55 r56 r57 r58 r59 r60 r61 r62 r63 r64 r65 +//@ revisions: r45 r46 r47 r48 r50 r51 r52 r53 r54 r55 r56 r57 r58 r59 r60 r61 r62 r63 r64 r65 //@ revisions: r66 r67 r68 r69 r70 r71 r72 r73 r74 r75 r76 r77 r78 r79 r80 r81 r82 r83 r84 r85 //@ assembly-output: emit-asm //@ [r1] compile-flags: --target aarch64-unknown-linux-gnu @@ -99,8 +99,8 @@ //@ [r47] needs-llvm-components: mips //@ [r48] compile-flags: --target mipsel-unknown-linux-musl //@ [r48] needs-llvm-components: mips -//@ [r49] compile-flags: --target nvptx64-nvidia-cuda -//@ [r49] needs-llvm-components: nvptx +//-@ [r49] compile-flags: --target nvptx64-nvidia-cuda [stack protector not supported on CUDA +//- see the test fail-stack-protector-unsupported] //@ [r50] compile-flags: --target powerpc-unknown-linux-gnu //@ [r50] needs-llvm-components: powerpc //@ [r51] compile-flags: --target powerpc64-unknown-linux-gnu @@ -173,7 +173,7 @@ //@ [r84] needs-llvm-components: x86 //@ [r85] compile-flags: --target x86_64-unknown-redox //@ [r85] needs-llvm-components: x86 -//@ compile-flags: -Z stack-protector=all -Cpanic=abort +//@ compile-flags: -C stack-protector=all -Cpanic=abort //@ compile-flags: -C opt-level=2 #![crate_type = "lib"] @@ -193,10 +193,6 @@ pub fn foo() { // r7: callq __security_check_cookie // r13: bl __security_check_cookie - // cuda doesn't support stack-smash protection - // r49-NOT: __security_check_cookie - // r49-NOT: __stack_chk_fail - // Other targets do stack checking within the function, and call a failure function on error // r1: __stack_chk_fail // r2: __stack_chk_fail diff --git a/tests/codegen-llvm/stack-protector.rs b/tests/codegen-llvm/stack-protector.rs index 8ab25b470cda1..1477d2ed7b28a 100644 --- a/tests/codegen-llvm/stack-protector.rs +++ b/tests/codegen-llvm/stack-protector.rs @@ -1,8 +1,10 @@ -//@ revisions: all strong basic none +//@ revisions: all all-z strong strong-z basic basic-z none strong-c-overrides-z //@ ignore-nvptx64 stack protector not supported -//@ [all] compile-flags: -Z stack-protector=all -//@ [strong] compile-flags: -Z stack-protector=strong -//@ [basic] compile-flags: -Z stack-protector=basic +//@ [all] compile-flags: -C stack-protector=all +//@ [all-z] compile-flags: -Z stack-protector=all +//@ [strong] compile-flags: -C stack-protector=strong +//@ [strong-z] compile-flags: -Z stack-protector=strong +//@ [strong-c-overrides-z] compile-flags: -C stack-protector=strong -Z stack-protector=all #![crate_type = "lib"] @@ -16,17 +18,29 @@ pub fn foo() { // all-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } // all-NOT: attributes #0 = { {{.*}}ssp {{.*}} } + // all-z-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } + // all-z-NOT: attributes #0 = { {{.*}}ssp {{.*}} } + // all-z: attributes #0 = { {{.*}}sspreq {{.*}} } + // all-z-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } + // all-z-NOT: attributes #0 = { {{.*}}ssp {{.*}} } + // strong-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } // strong-NOT: attributes #0 = { {{.*}}ssp {{.*}} } // strong: attributes #0 = { {{.*}}sspstrong {{.*}} } // strong-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } // strong-NOT: attributes #0 = { {{.*}}ssp {{.*}} } - // basic-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } - // basic-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } - // basic: attributes #0 = { {{.*}}ssp {{.*}} } - // basic-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } - // basic-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } + // strong-z-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } + // strong-z-NOT: attributes #0 = { {{.*}}ssp {{.*}} } + // strong-z: attributes #0 = { {{.*}}sspstrong {{.*}} } + // strong-z-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } + // strong-z-NOT: attributes #0 = { {{.*}}ssp {{.*}} } + + // strong-c-overrides-z-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } + // strong-c-overrides-z-NOT: attributes #0 = { {{.*}}ssp {{.*}} } + // strong-c-overrides-z: attributes #0 = { {{.*}}sspstrong {{.*}} } + // strong-c-overrides-z-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } + // strong-c-overrides-z-NOT: attributes #0 = { {{.*}}ssp {{.*}} } // none-NOT: attributes #0 = { {{.*}}sspreq {{.*}} } // none-NOT: attributes #0 = { {{.*}}sspstrong {{.*}} } diff --git a/tests/ui/README.md b/tests/ui/README.md index 9ef331698d2b6..fe203cb22c641 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -1300,7 +1300,7 @@ Stability attributes used internally by the standard library: `#[stable()]` and **FIXME**: Contains a single test, should likely be rehomed to `tests/ui/abi`. -## `tests/ui/stack-protector/`: `-Z stack-protector` command line flag +## `tests/ui/stack-protector/`: `-C stack-protector` command line flag See [Tracking Issue for stabilizing stack smashing protection (i.e., `-Z stack-protector`) #114903](https://github.com/rust-lang/rust/issues/114903). diff --git a/tests/ui/abi/stack-protector.rs b/tests/ui/abi/stack-protector.rs index dd0d0d43182ea..3c52d9ff1ae4d 100644 --- a/tests/ui/abi/stack-protector.rs +++ b/tests/ui/abi/stack-protector.rs @@ -1,7 +1,7 @@ //@ run-pass //@ only-x86_64-unknown-linux-gnu //@ revisions: ssp no-ssp -//@ [ssp] compile-flags: -Z stack-protector=all +//@ [ssp] compile-flags: -C stack-protector=all //@ compile-flags: -C opt-level=2 //@ compile-flags: -g //@ ignore-backends: gcc diff --git a/tests/ui/stack-protector/fail-stack-protector-unsupported.all-z.stderr b/tests/ui/stack-protector/fail-stack-protector-unsupported.all-z.stderr new file mode 100644 index 0000000000000..6c0f4347bbf4b --- /dev/null +++ b/tests/ui/stack-protector/fail-stack-protector-unsupported.all-z.stderr @@ -0,0 +1,4 @@ +error: `-C stack-protector=all` is not supported for target nvptx64-nvidia-cuda and will be ignored + +error: aborting due to 1 previous error + diff --git a/tests/ui/stack-protector/fail-stack-protector-unsupported.all.stderr b/tests/ui/stack-protector/fail-stack-protector-unsupported.all.stderr new file mode 100644 index 0000000000000..6c0f4347bbf4b --- /dev/null +++ b/tests/ui/stack-protector/fail-stack-protector-unsupported.all.stderr @@ -0,0 +1,4 @@ +error: `-C stack-protector=all` is not supported for target nvptx64-nvidia-cuda and will be ignored + +error: aborting due to 1 previous error + diff --git a/tests/ui/stack-protector/fail-stack-protector-unsupported.rs b/tests/ui/stack-protector/fail-stack-protector-unsupported.rs new file mode 100644 index 0000000000000..006c4b1d3a187 --- /dev/null +++ b/tests/ui/stack-protector/fail-stack-protector-unsupported.rs @@ -0,0 +1,31 @@ +//@ check-fail +//@ revisions: all strong all-z +//@ compile-flags: --target nvptx64-nvidia-cuda +//@ needs-llvm-components: nvptx +//@ [all] compile-flags: -C stack-protector=all +//@ [strong] compile-flags: -C stack-protector=strong +//@ [all-z] compile-flags: -Z stack-protector=all +//@ ignore-backends: gcc + +#![crate_type = "lib"] +#![feature(no_core, lang_items)] +#![no_std] +#![no_core] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +trait Sized: MetaSized {} + +#[lang = "copy"] +trait Copy {} + +pub fn main(){} + +//[all]~? ERROR `-C stack-protector=all` is not supported for target nvptx64-nvidia-cuda +//[all-z]~? ERROR `-C stack-protector=all` is not supported for target nvptx64-nvidia-cuda +//[strong]~? ERROR `-C stack-protector=strong` is not supported for target nvptx64-nvidia-cuda diff --git a/tests/ui/stack-protector/fail-stack-protector-unsupported.strong.stderr b/tests/ui/stack-protector/fail-stack-protector-unsupported.strong.stderr new file mode 100644 index 0000000000000..9cfa8644a55d7 --- /dev/null +++ b/tests/ui/stack-protector/fail-stack-protector-unsupported.strong.stderr @@ -0,0 +1,4 @@ +error: `-C stack-protector=strong` is not supported for target nvptx64-nvidia-cuda and will be ignored + +error: aborting due to 1 previous error + diff --git a/tests/ui/stack-protector/no-stack-protector-basic.rs b/tests/ui/stack-protector/no-stack-protector-basic.rs new file mode 100644 index 0000000000000..80f0e9b5d8c38 --- /dev/null +++ b/tests/ui/stack-protector/no-stack-protector-basic.rs @@ -0,0 +1,9 @@ +//@ check-fail +//@ revisions: stable unstable +//@ [unstable] compile-flags: -Z stack-protector=basic +//@ [stable] compile-flags: -C stack-protector=basic + +pub fn main(){} + +//[unstable]~? ERROR incorrect value `basic` for unstable option `stack-protector` +//[stable]~? ERROR incorrect value `basic` for codegen option `stack-protector` diff --git a/tests/ui/stack-protector/no-stack-protector-basic.stable.stderr b/tests/ui/stack-protector/no-stack-protector-basic.stable.stderr new file mode 100644 index 0000000000000..644c3e6a34f2a --- /dev/null +++ b/tests/ui/stack-protector/no-stack-protector-basic.stable.stderr @@ -0,0 +1,2 @@ +error: incorrect value `basic` for codegen option `stack-protector` - one of (`none` (default), `strong`, or `all`) was expected + diff --git a/tests/ui/stack-protector/no-stack-protector-basic.unstable.stderr b/tests/ui/stack-protector/no-stack-protector-basic.unstable.stderr new file mode 100644 index 0000000000000..7ee0f6ae03f3d --- /dev/null +++ b/tests/ui/stack-protector/no-stack-protector-basic.unstable.stderr @@ -0,0 +1,2 @@ +error: incorrect value `basic` for unstable option `stack-protector` - one of (`none` (default), `strong`, or `all`) was expected + diff --git a/tests/ui/stack-protector/warn-stack-protector-unsupported.all.stderr b/tests/ui/stack-protector/warn-stack-protector-unsupported.all.stderr deleted file mode 100644 index 54887715523c1..0000000000000 --- a/tests/ui/stack-protector/warn-stack-protector-unsupported.all.stderr +++ /dev/null @@ -1,4 +0,0 @@ -warning: `-Z stack-protector=all` is not supported for target nvptx64-nvidia-cuda and will be ignored - -warning: 1 warning emitted - diff --git a/tests/ui/stack-protector/warn-stack-protector-unsupported.basic.stderr b/tests/ui/stack-protector/warn-stack-protector-unsupported.basic.stderr deleted file mode 100644 index f7a1ee39fb9af..0000000000000 --- a/tests/ui/stack-protector/warn-stack-protector-unsupported.basic.stderr +++ /dev/null @@ -1,4 +0,0 @@ -warning: `-Z stack-protector=basic` is not supported for target nvptx64-nvidia-cuda and will be ignored - -warning: 1 warning emitted - diff --git a/tests/ui/stack-protector/warn-stack-protector-unsupported.rs b/tests/ui/stack-protector/warn-stack-protector-unsupported.rs deleted file mode 100644 index 9e0e126dabe66..0000000000000 --- a/tests/ui/stack-protector/warn-stack-protector-unsupported.rs +++ /dev/null @@ -1,31 +0,0 @@ -//@ build-pass -//@ revisions: all strong basic -//@ compile-flags: --target nvptx64-nvidia-cuda -//@ needs-llvm-components: nvptx -//@ [all] compile-flags: -Z stack-protector=all -//@ [strong] compile-flags: -Z stack-protector=strong -//@ [basic] compile-flags: -Z stack-protector=basic -//@ ignore-backends: gcc - -#![crate_type = "lib"] -#![feature(no_core, lang_items)] -#![no_std] -#![no_core] - -#[lang = "pointee_sized"] -pub trait PointeeSized {} - -#[lang = "meta_sized"] -pub trait MetaSized: PointeeSized {} - -#[lang = "sized"] -trait Sized: MetaSized {} - -#[lang = "copy"] -trait Copy {} - -pub fn main(){} - -//[all]~? WARN `-Z stack-protector=all` is not supported for target nvptx64-nvidia-cuda and will be ignored -//[strong]~? WARN `-Z stack-protector=strong` is not supported for target nvptx64-nvidia-cuda and will be ignored -//[basic]~? WARN `-Z stack-protector=basic` is not supported for target nvptx64-nvidia-cuda and will be ignored diff --git a/tests/ui/stack-protector/warn-stack-protector-unsupported.strong.stderr b/tests/ui/stack-protector/warn-stack-protector-unsupported.strong.stderr deleted file mode 100644 index ccc2f9f2cc5b8..0000000000000 --- a/tests/ui/stack-protector/warn-stack-protector-unsupported.strong.stderr +++ /dev/null @@ -1,4 +0,0 @@ -warning: `-Z stack-protector=strong` is not supported for target nvptx64-nvidia-cuda and will be ignored - -warning: 1 warning emitted -