@@ -19,6 +19,7 @@ pub(crate) struct RustcCodegenFlags<'a> {
1919 no_redzone : Option < bool > ,
2020 soft_float : Option < bool > ,
2121 dwarf_version : Option < u32 > ,
22+ stack_protector : Option < & ' a str > ,
2223}
2324
2425impl < ' this > RustcCodegenFlags < ' this > {
@@ -161,6 +162,12 @@ impl<'this> RustcCodegenFlags<'this> {
161162 "-Zdwarf-version must have a value" ,
162163 ) ) ?) ;
163164 }
165+ // https://github.com/rust-lang/rust/issues/114903
166+ // FIXME: Drop the -Z variant and update the doc link once the option is stabilized
167+ "-Zstack-protector" | "-Cstack-protector" => {
168+ self . stack_protector =
169+ Some ( flag_ok_or ( value, "-Zstack-protector must have a value" ) ?) ;
170+ }
164171 _ => { }
165172 }
166173 Ok ( ( ) )
@@ -267,6 +274,23 @@ impl<'this> RustcCodegenFlags<'this> {
267274 if let Some ( value) = self . dwarf_version {
268275 push_if_supported ( format ! ( "-gdwarf-{value}" ) . into ( ) ) ;
269276 }
277+ // https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fstack-protector
278+ // https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fstack-protector
279+ if let Some ( value) = self . stack_protector {
280+ // don't need to propagate stack-protector on MSVC since /GS is already the default
281+ // https://learn.microsoft.com/en-us/cpp/build/reference/gs-buffer-security-check?view=msvc-170
282+ //
283+ // Do NOT `stack-protector=none` since it weakens security for C code,
284+ // and `-Zstack-protector=basic` is deprecated and will be removed soon.
285+ let cc_flag = match value {
286+ "strong" => Some ( "-fstack-protector-strong" ) ,
287+ "all" => Some ( "-fstack-protector-all" ) ,
288+ _ => None ,
289+ } ;
290+ if let Some ( cc_flag) = cc_flag {
291+ push_if_supported ( cc_flag. into ( ) ) ;
292+ }
293+ }
270294 }
271295
272296 // Compiler-exclusive flags
@@ -379,6 +403,16 @@ mod tests {
379403 check ( "-L\u{1f} -Clto" , & expected) ;
380404 }
381405
406+ #[ test]
407+ fn stack_protector ( ) {
408+ let expected = RustcCodegenFlags {
409+ stack_protector : Some ( "strong" ) ,
410+ ..RustcCodegenFlags :: default ( )
411+ } ;
412+ check ( "-Zstack-protector=strong" , & expected) ;
413+ check ( "-Cstack-protector=strong" , & expected) ;
414+ }
415+
382416 #[ test]
383417 fn three_valid_prefixes ( ) {
384418 let expected = RustcCodegenFlags {
@@ -408,6 +442,7 @@ mod tests {
408442 "-Csoft-float=yes" ,
409443 "-Zbranch-protection=bti,pac-ret,leaf" ,
410444 "-Zdwarf-version=5" ,
445+ "-Zstack-protector=strong" ,
411446 // Set flags we don't recognise but rustc supports next
412447 // rustc flags
413448 "--cfg" ,
@@ -515,6 +550,7 @@ mod tests {
515550 soft_float : Some ( true ) ,
516551 branch_protection : Some ( "bti,pac-ret,leaf" ) ,
517552 dwarf_version : Some ( 5 ) ,
553+ stack_protector : Some ( "strong" ) ,
518554 } ,
519555 ) ;
520556 }
0 commit comments