diff --git a/src/doc/unstable-book/src/language-features/cfg-sanitize.md b/src/doc/unstable-book/src/language-features/cfg-sanitize.md new file mode 100644 index 0000000000000000000000000000000000000000..949f24ab9c11eb5337050c3fadfdc51bcf3bcf91 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/cfg-sanitize.md @@ -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 { + // ... + } +} + +``` + diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index d2ac5436cc8025e3e889462f593151fe1a1b620f..9a242d9d0769b4517278d009ec211d35be44ad8c 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -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 { @@ -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)); } diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 7c0d39965fc00ff0522ed544827aae6a2f4d35e9..16d8ada9f24c0857f93c2c29f662da0bfbd1d76c 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -524,6 +524,9 @@ pub fn set(&self, features: &mut Features, span: Span) { /// 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 // ------------------------------------------------------------------------- diff --git a/src/librustc_feature/builtin_attrs.rs b/src/librustc_feature/builtin_attrs.rs index 9c936492cbded40e3810566fdcd3a77be7bc1cde..4fa0198d8716d2463d49f9e1ca56f2cd58418040 100644 --- a/src/librustc_feature/builtin_attrs.rs +++ b/src/librustc_feature/builtin_attrs.rs @@ -25,6 +25,7 @@ (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. diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 7d43c3c8d076e93bc347bff192bdfbfed4937579..3059b059691067c51966b1646a1bcc35ec6e7892 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -177,6 +177,7 @@ cfg_attr, cfg_attr_multi, cfg_doctest, + cfg_sanitize, cfg_target_feature, cfg_target_has_atomic, cfg_target_thread_local, @@ -634,6 +635,7 @@ rust_eh_unwind_resume, rust_oom, rvalue_static_promotion, + sanitize, sanitizer_runtime, _Self, self_in_typedefs, diff --git a/src/test/ui/feature-gates/feature-gate-cfg_sanitize.rs b/src/test/ui/feature-gates/feature-gate-cfg_sanitize.rs new file mode 100644 index 0000000000000000000000000000000000000000..c3e7cc9ed8a9bcbe1252abf0cf281aaddcc2ac79 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-cfg_sanitize.rs @@ -0,0 +1,3 @@ +#[cfg(not(sanitize = "thread"))] +//~^ `cfg(sanitize)` is experimental +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-cfg_sanitize.stderr b/src/test/ui/feature-gates/feature-gate-cfg_sanitize.stderr new file mode 100644 index 0000000000000000000000000000000000000000..f67a0d83bdd3a1fab70eddaa13cf86d91cf6edf2 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-cfg_sanitize.stderr @@ -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`. diff --git a/src/test/ui/sanitize-cfg.rs b/src/test/ui/sanitize-cfg.rs new file mode 100644 index 0000000000000000000000000000000000000000..9c198543a86649572cd42aa4fc6105d4231b985b --- /dev/null +++ b/src/test/ui/sanitize-cfg.rs @@ -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() {}