Skip to content

Commit 7a75bbf

Browse files
authored
Rollup merge of rust-lang#66245 - tmiasko:cfg-sanitize, r=oli-obk
Conditional compilation for sanitizers Configure sanitize option when compiling with a sanitizer to make it possible to execute different code depending on whether given sanitizer is enabled or not.
2 parents 67a049d + c703ff2 commit 7a75bbf

File tree

8 files changed

+98
-0
lines changed

8 files changed

+98
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# `cfg_sanitize`
2+
3+
The tracking issue for this feature is: [#39699]
4+
5+
[#39699]: https://github.com/rust-lang/rust/issues/39699
6+
7+
------------------------
8+
9+
The `cfg_sanitize` feature makes it possible to execute different code
10+
depending on whether a particular sanitizer is enabled or not.
11+
12+
## Examples
13+
14+
``` rust
15+
#![feature(cfg_sanitize)]
16+
17+
#[cfg(sanitize = "thread")]
18+
fn a() {
19+
// ...
20+
}
21+
22+
#[cfg(not(sanitize = "thread"))]
23+
fn a() {
24+
// ...
25+
}
26+
27+
fn b() {
28+
if cfg!(sanitize = "leak") {
29+
// ...
30+
} else {
31+
// ...
32+
}
33+
}
34+
35+
```
36+

src/librustc/session/config.rs

+15
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ pub enum Sanitizer {
4747
Thread,
4848
}
4949

50+
impl fmt::Display for Sanitizer {
51+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52+
match *self {
53+
Sanitizer::Address => "address".fmt(f),
54+
Sanitizer::Leak => "leak".fmt(f),
55+
Sanitizer::Memory => "memory".fmt(f),
56+
Sanitizer::Thread => "thread".fmt(f),
57+
}
58+
}
59+
}
60+
5061
impl FromStr for Sanitizer {
5162
type Err = ();
5263
fn from_str(s: &str) -> Result<Sanitizer, ()> {
@@ -1580,6 +1591,10 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
15801591
}
15811592
}
15821593
}
1594+
if let Some(s) = &sess.opts.debugging_opts.sanitizer {
1595+
let symbol = Symbol::intern(&s.to_string());
1596+
ret.insert((sym::sanitize, Some(symbol)));
1597+
}
15831598
if sess.opts.debug_assertions {
15841599
ret.insert((Symbol::intern("debug_assertions"), None));
15851600
}

src/librustc_feature/active.rs

+3
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,9 @@ declare_features! (
524524
/// Allows the use of `if` and `match` in constants.
525525
(active, const_if_match, "1.41.0", Some(49146), None),
526526

527+
/// Allows the use of `#[cfg(sanitize = "option")]`; set when -Zsanitizer is used.
528+
(active, cfg_sanitize, "1.41.0", Some(39699), None),
529+
527530
// -------------------------------------------------------------------------
528531
// feature-group-end: actual feature gates
529532
// -------------------------------------------------------------------------

src/librustc_feature/builtin_attrs.rs

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const GATED_CFGS: &[GatedCfg] = &[
2525
(sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
2626
(sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
2727
(sym::target_has_atomic_load_store, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
28+
(sym::sanitize, sym::cfg_sanitize, cfg_fn!(cfg_sanitize)),
2829
];
2930

3031
/// Find a gated cfg determined by the `pred`icate which is given the cfg's name.

src/libsyntax_pos/symbol.rs

+2
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ symbols! {
177177
cfg_attr,
178178
cfg_attr_multi,
179179
cfg_doctest,
180+
cfg_sanitize,
180181
cfg_target_feature,
181182
cfg_target_has_atomic,
182183
cfg_target_thread_local,
@@ -634,6 +635,7 @@ symbols! {
634635
rust_eh_unwind_resume,
635636
rust_oom,
636637
rvalue_static_promotion,
638+
sanitize,
637639
sanitizer_runtime,
638640
_Self,
639641
self_in_typedefs,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#[cfg(not(sanitize = "thread"))]
2+
//~^ `cfg(sanitize)` is experimental
3+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0658]: `cfg(sanitize)` is experimental and subject to change
2+
--> $DIR/feature-gate-cfg_sanitize.rs:1:11
3+
|
4+
LL | #[cfg(not(sanitize = "thread"))]
5+
| ^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: for more information, see https://github.com/rust-lang/rust/issues/39699
8+
= help: add `#![feature(cfg_sanitize)]` to the crate attributes to enable
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0658`.

src/test/ui/sanitize-cfg.rs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Verifies that when compiling with -Zsanitizer=option,
2+
// the `#[cfg(sanitize = "option")]` attribute is configured.
3+
4+
// needs-sanitizer-support
5+
// only-linux
6+
// only-x86_64
7+
// check-pass
8+
// revisions: address leak memory thread
9+
//[address]compile-flags: -Zsanitizer=address --cfg address
10+
//[leak]compile-flags: -Zsanitizer=leak --cfg leak
11+
//[memory]compile-flags: -Zsanitizer=memory --cfg memory
12+
//[thread]compile-flags: -Zsanitizer=thread --cfg thread
13+
14+
#![feature(cfg_sanitize)]
15+
16+
#[cfg(all(sanitize = "address", address))]
17+
fn main() {}
18+
19+
#[cfg(all(sanitize = "leak", leak))]
20+
fn main() {}
21+
22+
#[cfg(all(sanitize = "memory", memory))]
23+
fn main() {}
24+
25+
#[cfg(all(sanitize = "thread", thread))]
26+
fn main() {}

0 commit comments

Comments
 (0)