about summary refs log tree commit diff
path: root/tests/ui/sanitize-attr
diff options
context:
space:
mode:
authorBastian Kersting <bkersting@google.com>2025-06-18 12:53:34 +0000
committerBastian Kersting <bkersting@google.com>2025-08-18 08:30:00 +0000
commit3ef065bf872ce62a18336dca0daf47b3e9f7da64 (patch)
treeb4dccd0b519642cac3b2f057995f5b378c8abc01 /tests/ui/sanitize-attr
parent425a9c0a0e365c0b8c6cfd00c2ded83a73bed9a0 (diff)
downloadrust-3ef065bf872ce62a18336dca0daf47b3e9f7da64.tar.gz
rust-3ef065bf872ce62a18336dca0daf47b3e9f7da64.zip
Implement the #[sanitize(..)] attribute
This change implements the #[sanitize(..)] attribute, which opts to
replace the currently unstable #[no_sanitize]. Essentially the new
attribute works similar as #[no_sanitize], just with more flexible
options regarding where it is applied. E.g. it is possible to turn
a certain sanitizer either on or off:
`#[sanitize(address = "on|off")]`

This attribute now also applies to more places, e.g. it is possible
to turn off a sanitizer for an entire module or impl block:
```rust
\#[sanitize(address = "off")]
mod foo {
    fn unsanitized(..) {}

    #[sanitize(address = "on")]
    fn sanitized(..) {}
}

\#[sanitize(thread = "off")]
impl MyTrait for () {
    ...
}
```

This attribute is enabled behind the unstable `sanitize` feature.
Diffstat (limited to 'tests/ui/sanitize-attr')
-rw-r--r--tests/ui/sanitize-attr/invalid-sanitize.rs22
-rw-r--r--tests/ui/sanitize-attr/invalid-sanitize.stderr82
-rw-r--r--tests/ui/sanitize-attr/valid-sanitize.rs115
-rw-r--r--tests/ui/sanitize-attr/valid-sanitize.stderr190
4 files changed, 409 insertions, 0 deletions
diff --git a/tests/ui/sanitize-attr/invalid-sanitize.rs b/tests/ui/sanitize-attr/invalid-sanitize.rs
new file mode 100644
index 00000000000..49dc01c8daa
--- /dev/null
+++ b/tests/ui/sanitize-attr/invalid-sanitize.rs
@@ -0,0 +1,22 @@
+#![feature(sanitize)]
+
+#[sanitize(brontosaurus = "off")] //~ ERROR invalid argument
+fn main() {
+}
+
+#[sanitize(address = "off")] //~ ERROR multiple `sanitize` attributes
+#[sanitize(address = "off")]
+fn multiple_consistent() {}
+
+#[sanitize(address = "on")] //~ ERROR multiple `sanitize` attributes
+#[sanitize(address = "off")]
+fn multiple_inconsistent() {}
+
+#[sanitize(address = "bogus")] //~ ERROR invalid argument for `sanitize`
+fn wrong_value() {}
+
+#[sanitize = "off"] //~ ERROR malformed `sanitize` attribute input
+fn name_value () {}
+
+#[sanitize] //~ ERROR malformed `sanitize` attribute input
+fn just_word() {}
diff --git a/tests/ui/sanitize-attr/invalid-sanitize.stderr b/tests/ui/sanitize-attr/invalid-sanitize.stderr
new file mode 100644
index 00000000000..bd36ce67b96
--- /dev/null
+++ b/tests/ui/sanitize-attr/invalid-sanitize.stderr
@@ -0,0 +1,82 @@
+error: malformed `sanitize` attribute input
+  --> $DIR/invalid-sanitize.rs:18:1
+   |
+LL | #[sanitize = "off"]
+   | ^^^^^^^^^^^^^^^^^^^
+   |
+help: the following are the possible correct uses
+   |
+LL - #[sanitize = "off"]
+LL + #[sanitize(address = "on|off")]
+   |
+LL - #[sanitize = "off"]
+LL + #[sanitize(cfi = "on|off")]
+   |
+LL - #[sanitize = "off"]
+LL + #[sanitize(hwaddress = "on|off")]
+   |
+LL - #[sanitize = "off"]
+LL + #[sanitize(kcfi = "on|off")]
+   |
+   = and 5 other candidates
+
+error: malformed `sanitize` attribute input
+  --> $DIR/invalid-sanitize.rs:21:1
+   |
+LL | #[sanitize]
+   | ^^^^^^^^^^^
+   |
+help: the following are the possible correct uses
+   |
+LL | #[sanitize(address = "on|off")]
+   |           ++++++++++++++++++++
+LL | #[sanitize(cfi = "on|off")]
+   |           ++++++++++++++++
+LL | #[sanitize(hwaddress = "on|off")]
+   |           ++++++++++++++++++++++
+LL | #[sanitize(kcfi = "on|off")]
+   |           +++++++++++++++++
+   = and 5 other candidates
+
+error: multiple `sanitize` attributes
+  --> $DIR/invalid-sanitize.rs:7:1
+   |
+LL | #[sanitize(address = "off")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+   |
+note: attribute also specified here
+  --> $DIR/invalid-sanitize.rs:8:1
+   |
+LL | #[sanitize(address = "off")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: multiple `sanitize` attributes
+  --> $DIR/invalid-sanitize.rs:11:1
+   |
+LL | #[sanitize(address = "on")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+   |
+note: attribute also specified here
+  --> $DIR/invalid-sanitize.rs:12:1
+   |
+LL | #[sanitize(address = "off")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: invalid argument for `sanitize`
+  --> $DIR/invalid-sanitize.rs:3:1
+   |
+LL | #[sanitize(brontosaurus = "off")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: expected one of: `address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow-call-stack`, or `thread`
+
+error: invalid argument for `sanitize`
+  --> $DIR/invalid-sanitize.rs:15:1
+   |
+LL | #[sanitize(address = "bogus")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: expected one of: `address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow-call-stack`, or `thread`
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/sanitize-attr/valid-sanitize.rs b/tests/ui/sanitize-attr/valid-sanitize.rs
new file mode 100644
index 00000000000..ebe76fcba04
--- /dev/null
+++ b/tests/ui/sanitize-attr/valid-sanitize.rs
@@ -0,0 +1,115 @@
+//! Tests where the `#[sanitize(..)]` attribute can and cannot be used.
+
+#![feature(sanitize)]
+#![feature(extern_types)]
+#![feature(impl_trait_in_assoc_type)]
+#![warn(unused_attributes)]
+#![sanitize(address = "off", thread = "on")]
+
+#[sanitize(address = "off", thread = "on")]
+mod submod {}
+
+#[sanitize(address = "off")]
+static FOO: u32 = 0;
+
+#[sanitize(thread = "off")] //~ ERROR sanitize attribute not allowed here
+static BAR: u32 = 0;
+
+#[sanitize(address = "off")] //~ ERROR sanitize attribute not allowed here
+type MyTypeAlias = ();
+
+#[sanitize(address = "off")] //~ ERROR sanitize attribute not allowed here
+trait MyTrait {
+    #[sanitize(address = "off")] //~ ERROR sanitize attribute not allowed here
+    const TRAIT_ASSOC_CONST: u32;
+
+    #[sanitize(address = "off")] //~ ERROR sanitize attribute not allowed here
+    type TraitAssocType;
+
+    #[sanitize(address = "off")] //~ ERROR sanitize attribute not allowed here
+    fn trait_method(&self);
+
+    #[sanitize(address = "off", thread = "on")]
+    fn trait_method_with_default(&self) {}
+
+    #[sanitize(address = "off")] //~ ERROR sanitize attribute not allowed here
+    fn trait_assoc_fn();
+}
+
+#[sanitize(address = "off")]
+impl MyTrait for () {
+    const TRAIT_ASSOC_CONST: u32 = 0;
+
+    #[sanitize(address = "off")] //~ ERROR sanitize attribute not allowed here
+    type TraitAssocType = Self;
+
+    #[sanitize(address = "off", thread = "on")]
+    fn trait_method(&self) {}
+    #[sanitize(address = "off", thread = "on")]
+    fn trait_method_with_default(&self) {}
+    #[sanitize(address = "off", thread = "on")]
+    fn trait_assoc_fn() {}
+}
+
+trait HasAssocType {
+    type T;
+    fn constrain_assoc_type() -> Self::T;
+}
+
+impl HasAssocType for () {
+    #[sanitize(address = "off")] //~ ERROR sanitize attribute not allowed here
+    type T = impl Copy;
+    fn constrain_assoc_type() -> Self::T {}
+}
+
+#[sanitize(address = "off")] //~ ERROR sanitize attribute not allowed here
+struct MyStruct {
+    #[sanitize(address = "off")] //~ ERROR sanitize attribute not allowed here
+    field: u32,
+}
+
+#[sanitize(address = "off", thread = "on")]
+impl MyStruct {
+    #[sanitize(address = "off", thread = "on")]
+    fn method(&self) {}
+    #[sanitize(address = "off", thread = "on")]
+    fn assoc_fn() {}
+}
+
+extern "C" {
+    #[sanitize(address = "off", thread = "on")] //~ ERROR sanitize attribute not allowed here
+    static X: u32;
+
+    #[sanitize(address = "off", thread = "on")] //~ ERROR sanitize attribute not allowed here
+    type T;
+
+    #[sanitize(address = "off", thread = "on")] //~ ERROR sanitize attribute not allowed here
+    fn foreign_fn();
+}
+
+#[sanitize(address = "off", thread = "on")]
+fn main() {
+    #[sanitize(address = "off", thread = "on")] //~ ERROR sanitize attribute not allowed here
+    let _ = ();
+
+    // Currently not allowed on let statements, even if they bind to a closure.
+    // It might be nice to support this as a special case someday, but trying
+    // to define the precise boundaries of that special case might be tricky.
+    #[sanitize(address = "off")] //~ ERROR sanitize attribute not allowed here
+    let _let_closure = || ();
+
+    // In situations where attributes can already be applied to expressions,
+    // the sanitize attribute is allowed on closure expressions.
+    let _closure_tail_expr = {
+        #[sanitize(address = "off", thread = "on")]
+        || ()
+    };
+
+    match () {
+        #[sanitize(address = "off")] //~ ERROR sanitize attribute not allowed here
+        () => (),
+    }
+
+    #[sanitize(address = "off")] //~ ERROR sanitize attribute not allowed here
+    return ();
+}
diff --git a/tests/ui/sanitize-attr/valid-sanitize.stderr b/tests/ui/sanitize-attr/valid-sanitize.stderr
new file mode 100644
index 00000000000..ff9fe63eaf5
--- /dev/null
+++ b/tests/ui/sanitize-attr/valid-sanitize.stderr
@@ -0,0 +1,190 @@
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:15:1
+   |
+LL | #[sanitize(thread = "off")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | static BAR: u32 = 0;
+   | -------------------- not a function, impl block, or module
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:18:1
+   |
+LL | #[sanitize(address = "off")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | type MyTypeAlias = ();
+   | ---------------------- not a function, impl block, or module
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:21:1
+   |
+LL |   #[sanitize(address = "off")]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / trait MyTrait {
+LL | |     #[sanitize(address = "off")]
+LL | |     const TRAIT_ASSOC_CONST: u32;
+...  |
+LL | |     fn trait_assoc_fn();
+LL | | }
+   | |_- not a function, impl block, or module
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:65:1
+   |
+LL |   #[sanitize(address = "off")]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / struct MyStruct {
+LL | |     #[sanitize(address = "off")]
+LL | |     field: u32,
+LL | | }
+   | |_- not a function, impl block, or module
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:67:5
+   |
+LL |     #[sanitize(address = "off")]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     field: u32,
+   |     ---------- not a function, impl block, or module
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:92:5
+   |
+LL |     #[sanitize(address = "off", thread = "on")]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let _ = ();
+   |     ----------- not a function, impl block, or module
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:98:5
+   |
+LL |     #[sanitize(address = "off")]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let _let_closure = || ();
+   |     ------------------------- not a function, impl block, or module
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:109:9
+   |
+LL |         #[sanitize(address = "off")]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         () => (),
+   |         -------- not a function, impl block, or module
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:113:5
+   |
+LL |     #[sanitize(address = "off")]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     return ();
+   |     --------- not a function, impl block, or module
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:23:5
+   |
+LL |     #[sanitize(address = "off")]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     const TRAIT_ASSOC_CONST: u32;
+   |     ----------------------------- not a function, impl block, or module
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:26:5
+   |
+LL |     #[sanitize(address = "off")]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     type TraitAssocType;
+   |     -------------------- not a function, impl block, or module
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:29:5
+   |
+LL |     #[sanitize(address = "off")]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fn trait_method(&self);
+   |     ----------------------- function has no body
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:35:5
+   |
+LL |     #[sanitize(address = "off")]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fn trait_assoc_fn();
+   |     -------------------- function has no body
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:43:5
+   |
+LL |     #[sanitize(address = "off")]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     type TraitAssocType = Self;
+   |     --------------------------- not a function, impl block, or module
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:60:5
+   |
+LL |     #[sanitize(address = "off")]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     type T = impl Copy;
+   |     ------------------- not a function, impl block, or module
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:80:5
+   |
+LL |     #[sanitize(address = "off", thread = "on")]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     static X: u32;
+   |     -------------- not a function, impl block, or module
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:83:5
+   |
+LL |     #[sanitize(address = "off", thread = "on")]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     type T;
+   |     ------- not a function, impl block, or module
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: sanitize attribute not allowed here
+  --> $DIR/valid-sanitize.rs:86:5
+   |
+LL |     #[sanitize(address = "off", thread = "on")]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fn foreign_fn();
+   |     ---------------- function has no body
+   |
+   = help: sanitize attribute can be applied to a function (with body), impl block, or module
+
+error: aborting due to 18 previous errors
+