about summary refs log tree commit diff
path: root/compiler/rustc_attr_parsing/src
diff options
context:
space:
mode:
authorJana Dönszelmann <jana@donsz.nl>2025-08-20 16:49:11 +0200
committerJana Dönszelmann <jana@donsz.nl>2025-08-23 12:31:07 +0200
commit1c03ae19dba16ffa95394927a4d91d30fc284910 (patch)
treeb375fb6d28716e2b27b3bcbfb755b714e166ff1f /compiler/rustc_attr_parsing/src
parent8df154bffddcb6bbb543ad69aff971795c5adbc2 (diff)
downloadrust-1c03ae19dba16ffa95394927a4d91d30fc284910.tar.gz
rust-1c03ae19dba16ffa95394927a4d91d30fc284910.zip
port attribute to the new parsing infrastructure
Diffstat (limited to 'compiler/rustc_attr_parsing/src')
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs113
-rw-r--r--compiler/rustc_attr_parsing/src/context.rs4
2 files changed, 110 insertions, 7 deletions
diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
index 91053811a0b..b884f8f3832 100644
--- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
@@ -1,4 +1,4 @@
-use rustc_hir::attrs::{CoverageAttrKind, OptimizeAttr, UsedBy};
+use rustc_hir::attrs::{CoverageAttrKind, OptimizeAttr, SanitizerSet, UsedBy};
 use rustc_session::parse::feature_err;
 
 use super::prelude::*;
@@ -464,6 +464,12 @@ impl<S: Stage> CombineAttributeParser<S> for ForceTargetFeatureParser {
         was_forced: true,
     };
     const TEMPLATE: AttributeTemplate = template!(List: &["enable = \"feat1, feat2\""]);
+    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
+        Allow(Target::Fn),
+        Allow(Target::Method(MethodKind::Inherent)),
+        Allow(Target::Method(MethodKind::Trait { body: true })),
+        Allow(Target::Method(MethodKind::TraitImpl)),
+    ]);
 
     fn extend<'c>(
         cx: &'c mut AcceptContext<'_, '_, S>,
@@ -471,11 +477,106 @@ impl<S: Stage> CombineAttributeParser<S> for ForceTargetFeatureParser {
     ) -> impl IntoIterator<Item = Self::Item> + 'c {
         parse_tf_attribute(cx, args)
     }
+}
 
-    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
-        Allow(Target::Fn),
-        Allow(Target::Method(MethodKind::Inherent)),
-        Allow(Target::Method(MethodKind::Trait { body: true })),
-        Allow(Target::Method(MethodKind::TraitImpl)),
+pub(crate) struct SanitizeParser;
+
+impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
+    const PATH: &[Symbol] = &[sym::sanitize];
+
+    // FIXME: still checked in check_attrs.rs
+    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
+
+    const TEMPLATE: AttributeTemplate = template!(List: &[
+        r#"address = "on|off""#,
+        r#"kernel_address = "on|off""#,
+        r#"cfi = "on|off""#,
+        r#"hwaddress = "on|off""#,
+        r#"kcfi = "on|off""#,
+        r#"memory = "on|off""#,
+        r#"memtag = "on|off""#,
+        r#"shadow_call_stack = "on|off""#,
+        r#"thread = "on|off""#
     ]);
+
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
+    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
+
+    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
+        let Some(list) = args.list() else {
+            cx.expected_list(cx.attr_span);
+            return None;
+        };
+
+        let mut on_set = SanitizerSet::empty();
+        let mut off_set = SanitizerSet::empty();
+
+        for item in list.mixed() {
+            let Some(item) = item.meta_item() else {
+                cx.expected_name_value(item.span(), None);
+                continue;
+            };
+
+            let path = item.path().word_sym();
+            let Some(value) = item.args().name_value() else {
+                cx.expected_name_value(item.span(), path);
+                continue;
+            };
+
+            let mut apply = |s: SanitizerSet| {
+                let is_on = match value.value_as_str() {
+                    Some(sym::on) => true,
+                    Some(sym::off) => false,
+                    Some(_) => {
+                        cx.expected_specific_argument_strings(
+                            value.value_span,
+                            &[sym::on, sym::off],
+                        );
+                        return;
+                    }
+                    None => {
+                        cx.expected_string_literal(value.value_span, Some(value.value_as_lit()));
+                        return;
+                    }
+                };
+
+                if is_on {
+                    on_set |= s;
+                } else {
+                    off_set |= s;
+                }
+            };
+
+            match path {
+                Some(sym::address) | Some(sym::kernel_address) => {
+                    apply(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS)
+                }
+                Some(sym::cfi) => apply(SanitizerSet::CFI),
+                Some(sym::kcfi) => apply(SanitizerSet::KCFI),
+                Some(sym::memory) => apply(SanitizerSet::MEMORY),
+                Some(sym::memtag) => apply(SanitizerSet::MEMTAG),
+                Some(sym::shadow_call_stack) => apply(SanitizerSet::SHADOWCALLSTACK),
+                Some(sym::thread) => apply(SanitizerSet::THREAD),
+                Some(sym::hwaddress) => apply(SanitizerSet::HWADDRESS),
+                _ => {
+                    cx.expected_specific_argument_strings(
+                        item.path().span(),
+                        &[
+                            sym::address,
+                            sym::cfi,
+                            sym::kcfi,
+                            sym::memory,
+                            sym::memtag,
+                            sym::shadow_call_stack,
+                            sym::thread,
+                            sym::hwaddress,
+                        ],
+                    );
+                    continue;
+                }
+            }
+        }
+
+        Some(AttributeKind::Sanitize { on_set, off_set, span: cx.attr_span })
+    }
 }
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index b9c415e8085..bb701df6053 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -20,7 +20,8 @@ use crate::attributes::allow_unstable::{
 use crate::attributes::body::CoroutineParser;
 use crate::attributes::codegen_attrs::{
     ColdParser, CoverageParser, ExportNameParser, ForceTargetFeatureParser, NakedParser,
-    NoMangleParser, OptimizeParser, TargetFeatureParser, TrackCallerParser, UsedParser,
+    NoMangleParser, OptimizeParser, SanitizeParser, TargetFeatureParser, TrackCallerParser,
+    UsedParser,
 };
 use crate::attributes::confusables::ConfusablesParser;
 use crate::attributes::deprecation::DeprecationParser;
@@ -184,6 +185,7 @@ attribute_parsers!(
         Single<RustcLayoutScalarValidRangeEnd>,
         Single<RustcLayoutScalarValidRangeStart>,
         Single<RustcObjectLifetimeDefaultParser>,
+        Single<SanitizeParser>,
         Single<ShouldPanicParser>,
         Single<SkipDuringMethodDispatchParser>,
         Single<TransparencyParser>,