Skip to content

Commit 16c1d0a

Browse files
committed
Maintain supported sanitizers as a target property
This commit adds an additional target property – `supported_sanitizers`, and replaces the hardcoded allowlists in argument parsing to use this new property. Fixes #81802
1 parent 64af7ea commit 16c1d0a

12 files changed

+49
-66
lines changed

compiler/rustc_session/src/session.rs

Lines changed: 16 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,59 +1517,22 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
15171517
);
15181518
}
15191519

1520-
const ASAN_SUPPORTED_TARGETS: &[&str] = &[
1521-
"aarch64-apple-darwin",
1522-
"aarch64-fuchsia",
1523-
"aarch64-unknown-linux-gnu",
1524-
"x86_64-apple-darwin",
1525-
"x86_64-fuchsia",
1526-
"x86_64-unknown-freebsd",
1527-
"x86_64-unknown-linux-gnu",
1528-
];
1529-
const LSAN_SUPPORTED_TARGETS: &[&str] = &[
1530-
"aarch64-apple-darwin",
1531-
"aarch64-unknown-linux-gnu",
1532-
"x86_64-apple-darwin",
1533-
"x86_64-unknown-linux-gnu",
1534-
];
1535-
const MSAN_SUPPORTED_TARGETS: &[&str] =
1536-
&["aarch64-unknown-linux-gnu", "x86_64-unknown-freebsd", "x86_64-unknown-linux-gnu"];
1537-
const TSAN_SUPPORTED_TARGETS: &[&str] = &[
1538-
"aarch64-apple-darwin",
1539-
"aarch64-unknown-linux-gnu",
1540-
"x86_64-apple-darwin",
1541-
"x86_64-unknown-freebsd",
1542-
"x86_64-unknown-linux-gnu",
1543-
];
1544-
const HWASAN_SUPPORTED_TARGETS: &[&str] =
1545-
&["aarch64-linux-android", "aarch64-unknown-linux-gnu"];
1546-
1547-
// Sanitizers can only be used on some tested platforms.
1548-
for s in sess.opts.debugging_opts.sanitizer {
1549-
let supported_targets = match s {
1550-
SanitizerSet::ADDRESS => ASAN_SUPPORTED_TARGETS,
1551-
SanitizerSet::LEAK => LSAN_SUPPORTED_TARGETS,
1552-
SanitizerSet::MEMORY => MSAN_SUPPORTED_TARGETS,
1553-
SanitizerSet::THREAD => TSAN_SUPPORTED_TARGETS,
1554-
SanitizerSet::HWADDRESS => HWASAN_SUPPORTED_TARGETS,
1555-
_ => panic!("unrecognized sanitizer {}", s),
1556-
};
1557-
if !supported_targets.contains(&&*sess.opts.target_triple.triple()) {
1558-
sess.err(&format!(
1559-
"`-Zsanitizer={}` only works with targets: {}",
1560-
s,
1561-
supported_targets.join(", ")
1562-
));
1563-
}
1564-
let conflicting = sess.opts.debugging_opts.sanitizer - s;
1565-
if !conflicting.is_empty() {
1566-
sess.err(&format!(
1567-
"`-Zsanitizer={}` is incompatible with `-Zsanitizer={}`",
1568-
s, conflicting,
1569-
));
1570-
// Don't report additional errors.
1571-
break;
1572-
}
1520+
// Sanitizers can only be used on platforms that we know have working sanitizer codegen.
1521+
let supported_sanitizers = sess.target.options.supported_sanitizers;
1522+
let unsupported_sanitizers = sess.opts.debugging_opts.sanitizer - supported_sanitizers;
1523+
match unsupported_sanitizers.into_iter().count() {
1524+
0 => {}
1525+
1 => sess
1526+
.err(&format!("{} sanitizer is not supported for this target", unsupported_sanitizers)),
1527+
_ => sess.err(&format!(
1528+
"{} sanitizers are not supported for this target",
1529+
unsupported_sanitizers
1530+
)),
1531+
}
1532+
// Cannot mix and match sanitizers.
1533+
let mut sanitizer_iter = sess.opts.debugging_opts.sanitizer.into_iter();
1534+
if let (Some(first), Some(second)) = (sanitizer_iter.next(), sanitizer_iter.next()) {
1535+
sess.err(&format!("`-Zsanitizer={}` is incompatible with `-Zsanitizer={}`", first, second));
15731536
}
15741537
}
15751538

compiler/rustc_target/src/spec/aarch64_apple_darwin.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
use crate::spec::{LinkerFlavor, Target, TargetOptions};
1+
use crate::spec::{LinkerFlavor, SanitizerSet, Target, TargetOptions};
22

33
pub fn target() -> Target {
44
let mut base = super::apple_base::opts("macos");
55
base.cpu = "apple-a12".to_string();
66
base.max_atomic_width = Some(128);
7-
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "arm64".to_string()]);
7+
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD;
88

9+
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "arm64".to_string()]);
910
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
1011

1112
// Clang automatically chooses a more specific target based on

compiler/rustc_target/src/spec/aarch64_fuchsia.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
use crate::spec::{Target, TargetOptions};
1+
use crate::spec::{SanitizerSet, Target, TargetOptions};
22

33
pub fn target() -> Target {
44
let mut base = super::fuchsia_base::opts();
55
base.max_atomic_width = Some(128);
6+
base.supported_sanitizers = SanitizerSet::ADDRESS;
67

78
Target {
89
llvm_target: "aarch64-fuchsia".to_string(),

compiler/rustc_target/src/spec/aarch64_linux_android.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::spec::{Target, TargetOptions};
1+
use crate::spec::{SanitizerSet, Target, TargetOptions};
22

33
// See https://developer.android.com/ndk/guides/abis.html#arm64-v8a
44
// for target ABI requirements.
@@ -9,6 +9,7 @@ pub fn target() -> Target {
99
// As documented in http://developer.android.com/ndk/guides/cpu-features.html
1010
// the neon (ASIMD) and FP must exist on all android aarch64 targets.
1111
base.features = "+neon,+fp-armv8".to_string();
12+
base.supported_sanitizers = SanitizerSet::HWADDRESS;
1213
Target {
1314
llvm_target: "aarch64-linux-android".to_string(),
1415
pointer_width: 64,

compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
use crate::spec::{Target, TargetOptions};
1+
use crate::spec::{SanitizerSet, Target, TargetOptions};
22

33
pub fn target() -> Target {
44
let mut base = super::linux_gnu_base::opts();
55
base.max_atomic_width = Some(128);
6+
base.supported_sanitizers = SanitizerSet::ADDRESS
7+
| SanitizerSet::LEAK
8+
| SanitizerSet::MEMORY
9+
| SanitizerSet::THREAD
10+
| SanitizerSet::HWADDRESS;
611

712
Target {
813
llvm_target: "aarch64-unknown-linux-gnu".to_string(),

compiler/rustc_target/src/spec/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ impl fmt::Display for SanitizerSet {
614614
_ => panic!("unrecognized sanitizer {:?}", s),
615615
};
616616
if !first {
617-
f.write_str(",")?;
617+
f.write_str(", ")?;
618618
}
619619
f.write_str(name)?;
620620
first = false;
@@ -1219,6 +1219,13 @@ pub struct TargetOptions {
12191219
/// How to handle split debug information, if at all. Specifying `None` has
12201220
/// target-specific meaning.
12211221
pub split_debuginfo: SplitDebuginfo,
1222+
1223+
/// The sanitizers supported by this target
1224+
///
1225+
/// Note that the support here is at a codegen level. If the machine code with sanitizer
1226+
/// enabled can generated on this target, but the necessary supporting libraries are not
1227+
/// distributed with the target, the sanitizer should still appear in this list for the target.
1228+
pub supported_sanitizers: SanitizerSet,
12221229
}
12231230

12241231
impl Default for TargetOptions {
@@ -1320,6 +1327,7 @@ impl Default for TargetOptions {
13201327
eh_frame_header: true,
13211328
has_thumb_interworking: false,
13221329
split_debuginfo: SplitDebuginfo::Off,
1330+
supported_sanitizers: SanitizerSet::empty(),
13231331
}
13241332
}
13251333
}

compiler/rustc_target/src/spec/x86_64_apple_darwin.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
1+
use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target, TargetOptions};
22

33
pub fn target() -> Target {
44
let mut base = super::apple_base::opts("macos");
@@ -11,6 +11,7 @@ pub fn target() -> Target {
1111
);
1212
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
1313
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
14+
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD;
1415

1516
// Clang automatically chooses a more specific target based on
1617
// MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work

compiler/rustc_target/src/spec/x86_64_fuchsia.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
use crate::spec::{StackProbeType, Target};
1+
use crate::spec::{SanitizerSet, StackProbeType, Target};
22

33
pub fn target() -> Target {
44
let mut base = super::fuchsia_base::opts();
55
base.cpu = "x86-64".to_string();
66
base.max_atomic_width = Some(64);
77
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
8+
base.supported_sanitizers = SanitizerSet::ADDRESS;
89

910
Target {
1011
llvm_target: "x86_64-fuchsia".to_string(),

compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
use crate::spec::{LinkerFlavor, StackProbeType, Target};
1+
use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target};
22

33
pub fn target() -> Target {
44
let mut base = super::freebsd_base::opts();
55
base.cpu = "x86-64".to_string();
66
base.max_atomic_width = Some(64);
77
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string());
88
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
9+
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::MEMORY | SanitizerSet::THREAD;
910

1011
Target {
1112
llvm_target: "x86_64-unknown-freebsd".to_string(),

compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
use crate::spec::{LinkerFlavor, StackProbeType, Target};
1+
use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target};
22

33
pub fn target() -> Target {
44
let mut base = super::linux_gnu_base::opts();
55
base.cpu = "x86-64".to_string();
66
base.max_atomic_width = Some(64);
77
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string());
88
base.stack_probes = StackProbeType::InlineOrCall { min_llvm_version_for_inline: (11, 0, 1) };
9+
base.supported_sanitizers =
10+
SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::THREAD;
911

1012
Target {
1113
llvm_target: "x86_64-unknown-linux-gnu".to_string(),
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// compile-flags: -Z sanitizer=leak --target i686-unknown-linux-gnu
2-
// error-pattern: error: `-Zsanitizer=leak` only works with targets:
3-
2+
// error-pattern: error: leak sanitizer is not supported for this target
43
#![feature(no_core)]
54
#![no_core]
65
#![no_main]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: `-Zsanitizer=leak` only works with targets: aarch64-apple-darwin, aarch64-unknown-linux-gnu, x86_64-apple-darwin, x86_64-unknown-linux-gnu
1+
error: leak sanitizer is not supported for this target
22

33
error: aborting due to previous error
44

0 commit comments

Comments
 (0)