about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src
diff options
context:
space:
mode:
authorBastian Kersting <bkersting@google.com>2025-06-18 13:47:44 +0000
committerBastian Kersting <bkersting@google.com>2025-08-18 08:45:28 +0000
commit95bdb34494ad795f552cab7a0eb7bfd2e98ef033 (patch)
tree452b242828e0dce60cd3f0b14f651e7509e13ff2 /compiler/rustc_codegen_ssa/src
parent3ef065bf872ce62a18336dca0daf47b3e9f7da64 (diff)
downloadrust-95bdb34494ad795f552cab7a0eb7bfd2e98ef033.tar.gz
rust-95bdb34494ad795f552cab7a0eb7bfd2e98ef033.zip
Remove the no_sanitize attribute in favor of sanitize
This removes the #[no_sanitize] attribute, which was behind an unstable
feature named no_sanitize. Instead, we introduce the sanitize attribute
which is more powerful and allows to be extended in the future (instead
of just focusing on turning sanitizers off).

This also makes sanitize(kernel_address = ..) attribute work with
-Zsanitize=address

To do it the same as how clang disables address sanitizer, we now
disable ASAN on sanitize(kernel_address = "off") and KASAN on
sanitize(address = "off").

The same was added to clang in https://reviews.llvm.org/D44981.
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs78
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs8
2 files changed, 22 insertions, 64 deletions
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 068559497dd..bf14c02a09c 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -77,32 +77,6 @@ fn parse_instruction_set_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> Option<Instr
     }
 }
 
-// FIXME(jdonszelmann): remove when no_sanitize becomes a parsed attr
-fn parse_no_sanitize_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> Option<SanitizerSet> {
-    let list = attr.meta_item_list()?;
-    let mut sanitizer_set = SanitizerSet::empty();
-
-    for item in list.iter() {
-        match item.name() {
-            Some(sym::address) => {
-                sanitizer_set |= SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS
-            }
-            Some(sym::cfi) => sanitizer_set |= SanitizerSet::CFI,
-            Some(sym::kcfi) => sanitizer_set |= SanitizerSet::KCFI,
-            Some(sym::memory) => sanitizer_set |= SanitizerSet::MEMORY,
-            Some(sym::memtag) => sanitizer_set |= SanitizerSet::MEMTAG,
-            Some(sym::shadow_call_stack) => sanitizer_set |= SanitizerSet::SHADOWCALLSTACK,
-            Some(sym::thread) => sanitizer_set |= SanitizerSet::THREAD,
-            Some(sym::hwaddress) => sanitizer_set |= SanitizerSet::HWADDRESS,
-            _ => {
-                tcx.dcx().emit_err(errors::InvalidNoSanitize { span: item.span() });
-            }
-        }
-    }
-
-    Some(sanitizer_set)
-}
-
 // FIXME(jdonszelmann): remove when patchable_function_entry becomes a parsed attr
 fn parse_patchable_function_entry(
     tcx: TyCtxt<'_>,
@@ -161,7 +135,6 @@ fn parse_patchable_function_entry(
 #[derive(Default)]
 struct InterestingAttributeDiagnosticSpans {
     link_ordinal: Option<Span>,
-    no_sanitize: Option<Span>,
     sanitize: Option<Span>,
     inline: Option<Span>,
     no_mangle: Option<Span>,
@@ -331,11 +304,6 @@ fn process_builtin_attrs(
                 codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED
             }
             sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL,
-            sym::no_sanitize => {
-                interesting_spans.no_sanitize = Some(attr.span());
-                codegen_fn_attrs.no_sanitize |=
-                    parse_no_sanitize_attr(tcx, attr).unwrap_or_default();
-            }
             sym::sanitize => interesting_spans.sanitize = Some(attr.span()),
             sym::instruction_set => {
                 codegen_fn_attrs.instruction_set = parse_instruction_set_attr(tcx, attr)
@@ -459,21 +427,10 @@ fn check_result(
     if !codegen_fn_attrs.no_sanitize.is_empty()
         && codegen_fn_attrs.inline.always()
         && let (Some(no_sanitize_span), Some(inline_span)) =
-            (interesting_spans.no_sanitize, interesting_spans.inline)
-    {
-        let hir_id = tcx.local_def_id_to_hir_id(did);
-        tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, no_sanitize_span, |lint| {
-            lint.primary_message("`no_sanitize` will have no effect after inlining");
-            lint.span_note(inline_span, "inlining requested here");
-        })
-    }
-    if !codegen_fn_attrs.no_sanitize.is_empty()
-        && codegen_fn_attrs.inline.always()
-        && let (Some(sanitize_span), Some(inline_span)) =
             (interesting_spans.sanitize, interesting_spans.inline)
     {
         let hir_id = tcx.local_def_id_to_hir_id(did);
-        tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, sanitize_span, |lint| {
+        tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, no_sanitize_span, |lint| {
             lint.primary_message("setting `sanitize` off will have no effect after inlining");
             lint.span_note(inline_span, "inlining requested here");
         })
@@ -601,9 +558,14 @@ fn opt_trait_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
 }
 
 /// For an attr that has the `sanitize` attribute, read the list of
-/// disabled sanitizers.
-fn parse_sanitize_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> SanitizerSet {
-    let mut result = SanitizerSet::empty();
+/// disabled sanitizers. `current_attr` holds the information about
+/// previously parsed attributes.
+fn parse_sanitize_attr(
+    tcx: TyCtxt<'_>,
+    attr: &Attribute,
+    current_attr: SanitizerSet,
+) -> SanitizerSet {
+    let mut result = current_attr;
     if let Some(list) = attr.meta_item_list() {
         for item in list.iter() {
             let MetaItemInner::MetaItem(set) = item else {
@@ -612,10 +574,13 @@ fn parse_sanitize_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> SanitizerSet {
             };
             let segments = set.path.segments.iter().map(|x| x.ident.name).collect::<Vec<_>>();
             match segments.as_slice() {
-                [sym::address] if set.value_str() == Some(sym::off) => {
+                // Similar to clang, sanitize(address = ..) and
+                // sanitize(kernel_address = ..) control both ASan and KASan
+                // Source: https://reviews.llvm.org/D44981.
+                [sym::address] | [sym::kernel_address] if set.value_str() == Some(sym::off) => {
                     result |= SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS
                 }
-                [sym::address] if set.value_str() == Some(sym::on) => {
+                [sym::address] | [sym::kernel_address] if set.value_str() == Some(sym::on) => {
                     result &= !SanitizerSet::ADDRESS;
                     result &= !SanitizerSet::KERNELADDRESS;
                 }
@@ -663,19 +628,20 @@ fn parse_sanitize_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> SanitizerSet {
 }
 
 fn disabled_sanitizers_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerSet {
-    // Check for a sanitize annotation directly on this def.
-    if let Some(attr) = tcx.get_attr(did, sym::sanitize) {
-        return parse_sanitize_attr(tcx, attr);
-    }
-
-    // Otherwise backtrack.
-    match tcx.opt_local_parent(did) {
+    // Backtrack to the crate root.
+    let disabled = match tcx.opt_local_parent(did) {
         // Check the parent (recursively).
         Some(parent) => tcx.disabled_sanitizers_for(parent),
         // We reached the crate root without seeing an attribute, so
         // there is no sanitizers to exclude.
         None => SanitizerSet::empty(),
+    };
+
+    // Check for a sanitize annotation directly on this def.
+    if let Some(attr) = tcx.get_attr(did, sym::sanitize) {
+        return parse_sanitize_attr(tcx, attr, disabled);
     }
+    disabled
 }
 
 /// Checks if the provided DefId is a method in a trait impl for a trait which has track_caller
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index 913e0025f2e..209c78ddeda 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -1121,14 +1121,6 @@ impl IntoDiagArg for ExpectedPointerMutability {
 }
 
 #[derive(Diagnostic)]
-#[diag(codegen_ssa_invalid_no_sanitize)]
-#[note]
-pub(crate) struct InvalidNoSanitize {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(codegen_ssa_invalid_sanitize)]
 #[note]
 pub(crate) struct InvalidSanitize {