about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2019-12-02 09:34:09 +0100
committerGitHub <noreply@github.com>2019-12-02 09:34:09 +0100
commit8438770e1fc647bc06745cfafc4da32dcc5b85b2 (patch)
treee34c4cc093f3d1ebbf71deb279fd2dc047e4e594
parentf5c81e0a986e4285d3d0fd781a1bd475753eb12c (diff)
parentc703ff26555bc25739384b2104dfb538ec7435c7 (diff)
downloadrust-8438770e1fc647bc06745cfafc4da32dcc5b85b2.tar.gz
rust-8438770e1fc647bc06745cfafc4da32dcc5b85b2.zip
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.
-rw-r--r--src/doc/unstable-book/src/language-features/cfg-sanitize.md36
-rw-r--r--src/librustc/session/config.rs15
-rw-r--r--src/librustc_feature/active.rs3
-rw-r--r--src/librustc_feature/builtin_attrs.rs1
-rw-r--r--src/libsyntax_pos/symbol.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-cfg_sanitize.rs3
-rw-r--r--src/test/ui/feature-gates/feature-gate-cfg_sanitize.stderr12
-rw-r--r--src/test/ui/sanitize-cfg.rs26
8 files changed, 98 insertions, 0 deletions
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 00000000000..949f24ab9c1
--- /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 d2ac5436cc8..9a242d9d076 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<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));
     }
diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs
index 7c0d39965fc..16d8ada9f24 100644
--- a/src/librustc_feature/active.rs
+++ b/src/librustc_feature/active.rs
@@ -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
     // -------------------------------------------------------------------------
diff --git a/src/librustc_feature/builtin_attrs.rs b/src/librustc_feature/builtin_attrs.rs
index 9c936492cbd..4fa0198d871 100644
--- a/src/librustc_feature/builtin_attrs.rs
+++ b/src/librustc_feature/builtin_attrs.rs
@@ -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.
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 7d43c3c8d07..3059b059691 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -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,
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 00000000000..c3e7cc9ed8a
--- /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 00000000000..f67a0d83bdd
--- /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 00000000000..9c198543a86
--- /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() {}