Rollup merge of #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.
This commit is contained in:
commit
8438770e1f
36
src/doc/unstable-book/src/language-features/cfg-sanitize.md
Normal file
36
src/doc/unstable-book/src/language-features/cfg-sanitize.md
Normal file
@ -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 {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
@ -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, ()> {
|
||||
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
@ -634,6 +635,7 @@ symbols! {
|
||||
rust_eh_unwind_resume,
|
||||
rust_oom,
|
||||
rvalue_static_promotion,
|
||||
sanitize,
|
||||
sanitizer_runtime,
|
||||
_Self,
|
||||
self_in_typedefs,
|
||||
|
3
src/test/ui/feature-gates/feature-gate-cfg_sanitize.rs
Normal file
3
src/test/ui/feature-gates/feature-gate-cfg_sanitize.rs
Normal file
@ -0,0 +1,3 @@
|
||||
#[cfg(not(sanitize = "thread"))]
|
||||
//~^ `cfg(sanitize)` is experimental
|
||||
fn main() {}
|
12
src/test/ui/feature-gates/feature-gate-cfg_sanitize.stderr
Normal file
12
src/test/ui/feature-gates/feature-gate-cfg_sanitize.stderr
Normal file
@ -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
src/test/ui/sanitize-cfg.rs
Normal file
26
src/test/ui/sanitize-cfg.rs
Normal file
@ -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() {}
|
Loading…
x
Reference in New Issue
Block a user