Skip to content

Commit

Permalink
Rollup merge of rust-lang#66245 - tmiasko:cfg-sanitize, r=oli-obk
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
RalfJung authored Dec 2, 2019
2 parents f5c81e0 + c703ff2 commit 8438770
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/doc/unstable-book/src/language-features/cfg-sanitize.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# `cfg_sanitize`

The tracking issue for this feature is: [#39699]

[#39699]: https://github.com/rust-lang/rust/issues/39699

------------------------

The `cfg_sanitize` feature makes it possible to execute different code
depending on whether a particular sanitizer is enabled or not.

## Examples

``` rust
#![feature(cfg_sanitize)]

#[cfg(sanitize = "thread")]
fn a() {
// ...
}

#[cfg(not(sanitize = "thread"))]
fn a() {
// ...
}

fn b() {
if cfg!(sanitize = "leak") {
// ...
} else {
// ...
}
}

```

15 changes: 15 additions & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ pub enum Sanitizer {
Thread,
}

impl fmt::Display for Sanitizer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Sanitizer::Address => "address".fmt(f),
Sanitizer::Leak => "leak".fmt(f),
Sanitizer::Memory => "memory".fmt(f),
Sanitizer::Thread => "thread".fmt(f),
}
}
}

impl FromStr for Sanitizer {
type Err = ();
fn from_str(s: &str) -> Result<Sanitizer, ()> {
Expand Down Expand Up @@ -1580,6 +1591,10 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
}
}
}
if let Some(s) = &sess.opts.debugging_opts.sanitizer {
let symbol = Symbol::intern(&s.to_string());
ret.insert((sym::sanitize, Some(symbol)));
}
if sess.opts.debug_assertions {
ret.insert((Symbol::intern("debug_assertions"), None));
}
Expand Down
3 changes: 3 additions & 0 deletions src/librustc_feature/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,9 @@ declare_features! (
/// Allows the use of `if` and `match` in constants.
(active, const_if_match, "1.41.0", Some(49146), None),

/// Allows the use of `#[cfg(sanitize = "option")]`; set when -Zsanitizer is used.
(active, cfg_sanitize, "1.41.0", Some(39699), None),

// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions src/librustc_feature/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const GATED_CFGS: &[GatedCfg] = &[
(sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
(sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
(sym::target_has_atomic_load_store, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
(sym::sanitize, sym::cfg_sanitize, cfg_fn!(cfg_sanitize)),
];

/// Find a gated cfg determined by the `pred`icate which is given the cfg's name.
Expand Down
2 changes: 2 additions & 0 deletions src/libsyntax_pos/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ symbols! {
cfg_attr,
cfg_attr_multi,
cfg_doctest,
cfg_sanitize,
cfg_target_feature,
cfg_target_has_atomic,
cfg_target_thread_local,
Expand Down Expand Up @@ -634,6 +635,7 @@ symbols! {
rust_eh_unwind_resume,
rust_oom,
rvalue_static_promotion,
sanitize,
sanitizer_runtime,
_Self,
self_in_typedefs,
Expand Down
3 changes: 3 additions & 0 deletions src/test/ui/feature-gates/feature-gate-cfg_sanitize.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#[cfg(not(sanitize = "thread"))]
//~^ `cfg(sanitize)` is experimental
fn main() {}
12 changes: 12 additions & 0 deletions src/test/ui/feature-gates/feature-gate-cfg_sanitize.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0658]: `cfg(sanitize)` is experimental and subject to change
--> $DIR/feature-gate-cfg_sanitize.rs:1:11
|
LL | #[cfg(not(sanitize = "thread"))]
| ^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/39699
= help: add `#![feature(cfg_sanitize)]` to the crate attributes to enable

error: aborting due to previous error

For more information about this error, try `rustc --explain E0658`.
26 changes: 26 additions & 0 deletions src/test/ui/sanitize-cfg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Verifies that when compiling with -Zsanitizer=option,
// the `#[cfg(sanitize = "option")]` attribute is configured.

// needs-sanitizer-support
// only-linux
// only-x86_64
// check-pass
// revisions: address leak memory thread
//[address]compile-flags: -Zsanitizer=address --cfg address
//[leak]compile-flags: -Zsanitizer=leak --cfg leak
//[memory]compile-flags: -Zsanitizer=memory --cfg memory
//[thread]compile-flags: -Zsanitizer=thread --cfg thread

#![feature(cfg_sanitize)]

#[cfg(all(sanitize = "address", address))]
fn main() {}

#[cfg(all(sanitize = "leak", leak))]
fn main() {}

#[cfg(all(sanitize = "memory", memory))]
fn main() {}

#[cfg(all(sanitize = "thread", thread))]
fn main() {}

0 comments on commit 8438770

Please sign in to comment.