Skip to content

Commit 5e1485d

Browse files
Rollup merge of rust-lang#157788 - PiJoules:multiple-sanitizer-flags, r=petrochenkov
Accumulate multiple -Zsanitizer target modifiers When passing multiple `-Zsanitizer` flags to the compiler (e.g., `-Zsanitizer=address -Zsanitizer=shadow-call-stack`), the options parser was overwriting the previous values in `target_modifiers` instead of accumulating them. This resulted in only the last sanitizer being recorded in the crate metadata's target modifiers, even though the frontend correctly enabled all of them. The only way to provide multiple sanitizers is to combine them into a comma-separated list passed to a single `-Zsanitizer=` flag, but this doesn't fit very well into the GN build system where different targets may pass different combinations of sanitizer flags. Consequently, this caused spurious "incompatible target modifiers" ABI mismatch errors when linking against dependencies compiled with accumulated flags. Fix this by entry-modifying the `target_modifiers` map to accumulate the sanitizers as a comma-separated list when the option is `sanitizer`.
2 parents 022cd10 + dad6583 commit 5e1485d

6 files changed

Lines changed: 41 additions & 5 deletions

File tree

compiler/rustc_session/src/options.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,25 @@ fn build_options<O: Default>(
727727
}
728728
if let Some(tmod) = *tmod {
729729
let v = value.map_or(String::new(), ToOwned::to_owned);
730-
collected_options.target_modifiers.insert(tmod, v);
730+
731+
// Accumulate all the -Zsanitizer flags into a single target modifier.
732+
match tmod {
733+
OptionsTargetModifiers::UnstableOptions(
734+
UnstableOptionsTargetModifiers::Sanitizer,
735+
) => {
736+
collected_options
737+
.target_modifiers
738+
.entry(tmod)
739+
.and_modify(|existing| {
740+
existing.push(',');
741+
existing.push_str(&v);
742+
})
743+
.or_insert(v);
744+
}
745+
_ => {
746+
collected_options.target_modifiers.insert(tmod, v);
747+
}
748+
}
731749
}
732750
if let Some(mitigation) = mitigation {
733751
collected_options.mitigations.reset_mitigation(*mitigation, index);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Verifies that multiple compatible sanitizers (CFI + SafeStack) can be enabled together
2+
// and their target modifiers accumulate instead of overwriting.
3+
//
4+
//@ only-x86_64
5+
//@ only-linux
6+
//@ compile-flags: -Zsanitizer=cfi -Zsanitizer=safestack -Clto -Ccodegen-units=1 -C unsafe-allow-abi-mismatch=sanitizer
7+
8+
#![crate_type = "lib"]
9+
10+
// CHECK: ; Function Attrs:{{.*}}safestack
11+
// CHECK: define{{.*}}foo{{.*}}!type
12+
pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 {
13+
f(arg)
14+
}
15+
16+
// CHECK: attributes #0 = {{.*}}safestack{{.*}}

tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_both.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizers_safestack_and_kcfi`
2-
--> $DIR/sanitizers-safestack-and-kcfi.rs:16:1
2+
--> $DIR/sanitizers-safestack-and-kcfi.rs:18:1
33
|
44
LL | #![feature(no_core)]
55
| ^

tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_kcfi.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizers_safestack_and_kcfi`
2-
--> $DIR/sanitizers-safestack-and-kcfi.rs:16:1
2+
--> $DIR/sanitizers-safestack-and-kcfi.rs:18:1
33
|
44
LL | #![feature(no_core)]
55
| ^

tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_safestack.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizers_safestack_and_kcfi`
2-
--> $DIR/sanitizers-safestack-and-kcfi.rs:16:1
2+
--> $DIR/sanitizers-safestack-and-kcfi.rs:18:1
33
|
44
LL | #![feature(no_core)]
55
| ^

tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44
//@ aux-build:safestack-and-kcfi.rs
55
//@ compile-flags: -Cpanic=abort
66

7-
//@ revisions: good good_reverted missed_safestack missed_kcfi missed_both
7+
//@ revisions: good good_reverted good_multiple missed_safestack missed_kcfi missed_both
88
//@[good] compile-flags: -Zsanitizer=safestack,kcfi
99
//@[good_reverted] compile-flags: -Zsanitizer=kcfi,safestack
10+
//@[good_multiple] compile-flags: -Zsanitizer=safestack -Zsanitizer=kcfi
1011
//@[missed_safestack] compile-flags: -Zsanitizer=kcfi
1112
//@[missed_kcfi] compile-flags: -Zsanitizer=safestack
1213
// [missed_both] no additional compile-flags:
1314
//@[good] check-pass
1415
//@[good_reverted] check-pass
16+
//@[good_multiple] check-pass
1517

1618
#![feature(no_core)]
1719
//[missed_safestack]~^ ERROR mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizers_safestack_and_kcfi`

0 commit comments

Comments
 (0)