From bc883e24b8e1719f843ccf8be0217c1207425715 Mon Sep 17 00:00:00 2001 From: Lucas Baumann Date: Sat, 26 Jul 2025 12:02:35 +0200 Subject: [PATCH] replace SanitizerSet in CodegenFnAttrs by new type --- compiler/rustc_codegen_llvm/src/attributes.rs | 8 ++--- compiler/rustc_codegen_llvm/src/base.rs | 8 ++--- compiler/rustc_codegen_llvm/src/builder.rs | 4 +-- .../rustc_codegen_ssa/src/codegen_attrs.rs | 30 +++++++++---------- compiler/rustc_middle/src/lib.rs | 2 ++ .../src/middle/codegen_fn_attrs.rs | 20 ++++++++++--- compiler/rustc_middle/src/query/erase.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 8 ++--- compiler/rustc_mir_transform/src/inline.rs | 2 +- tests/ui/sanitizer/inline-always-sanitize.rs | 2 +- .../sanitizer/inline-always-sanitize.stderr | 2 +- 11 files changed, 51 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 96af90cd272b..7b8b7ff3c291 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -2,7 +2,7 @@ use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::{ - CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, + CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs, }; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet}; @@ -98,10 +98,10 @@ fn patchable_function_entry_attrs<'ll>( pub(crate) fn sanitize_attrs<'ll, 'tcx>( cx: &SimpleCx<'ll>, tcx: TyCtxt<'tcx>, - no_sanitize: SanitizerSet, + sanitizer_fn_attr: SanitizerFnAttrs, ) -> SmallVec<[&'ll Attribute; 4]> { let mut attrs = SmallVec::new(); - let enabled = tcx.sess.sanitizers() - no_sanitize; + let enabled = tcx.sess.sanitizers() - sanitizer_fn_attr.disabled; if enabled.contains(SanitizerSet::ADDRESS) || enabled.contains(SanitizerSet::KERNELADDRESS) { attrs.push(llvm::AttributeKind::SanitizeAddress.create_attr(cx.llcx)); } @@ -411,7 +411,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( // not used. } else { // Do not set sanitizer attributes for naked functions. - to_add.extend(sanitize_attrs(cx, tcx, codegen_fn_attrs.no_sanitize)); + to_add.extend(sanitize_attrs(cx, tcx, codegen_fn_attrs.sanitizers)); // For non-naked functions, set branch protection attributes on aarch64. if let Some(BranchProtection { bti, pac_ret, gcs }) = diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 4523d629b1ef..6cbddfec4631 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -20,7 +20,7 @@ use rustc_codegen_ssa::traits::*; use rustc_data_structures::small_c_str::SmallCStr; use rustc_hir::attrs::Linkage; use rustc_middle::dep_graph; -use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; +use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrs, SanitizerFnAttrs}; use rustc_middle::mir::mono::Visibility; use rustc_middle::ty::TyCtxt; use rustc_session::config::DebugInfo; @@ -105,7 +105,7 @@ pub(crate) fn compile_codegen_unit( if let Some(entry) = maybe_create_entry_wrapper::>(&cx, cx.codegen_unit) { - let attrs = attributes::sanitize_attrs(&cx, tcx, SanitizerSet::empty()); + let attrs = attributes::sanitize_attrs(&cx, tcx, SanitizerFnAttrs::default()); attributes::apply_to_llfn(entry, llvm::AttributePlace::Function, &attrs); } @@ -191,10 +191,10 @@ pub(crate) fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility { } pub(crate) fn set_variable_sanitizer_attrs(llval: &Value, attrs: &CodegenFnAttrs) { - if attrs.no_sanitize.contains(SanitizerSet::ADDRESS) { + if attrs.sanitizers.disabled.contains(SanitizerSet::ADDRESS) { unsafe { llvm::LLVMRustSetNoSanitizeAddress(llval) }; } - if attrs.no_sanitize.contains(SanitizerSet::HWADDRESS) { + if attrs.sanitizers.disabled.contains(SanitizerSet::HWADDRESS) { unsafe { llvm::LLVMRustSetNoSanitizeHWAddress(llval) }; } } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index d441cd119a74..4cef7bff9206 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1798,7 +1798,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { && is_indirect_call { if let Some(fn_attrs) = fn_attrs - && fn_attrs.no_sanitize.contains(SanitizerSet::CFI) + && fn_attrs.sanitizers.disabled.contains(SanitizerSet::CFI) { return; } @@ -1856,7 +1856,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { && is_indirect_call { if let Some(fn_attrs) = fn_attrs - && fn_attrs.no_sanitize.contains(SanitizerSet::KCFI) + && fn_attrs.sanitizers.disabled.contains(SanitizerSet::KCFI) { return None; } diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 44de48a3ada5..5dd1365f2645 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -8,7 +8,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::{self as hir, Attribute, LangItem, find_attr, lang_items}; use rustc_middle::middle::codegen_fn_attrs::{ - CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, + CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs, }; use rustc_middle::query::Providers; use rustc_middle::span_bug; @@ -16,7 +16,6 @@ use rustc_middle::ty::{self as ty, TyCtxt}; use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::{Ident, Span, sym}; -use rustc_target::spec::SanitizerSet; use crate::errors; use crate::target_features::{ @@ -351,7 +350,8 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code Ord::max(codegen_fn_attrs.alignment, tcx.sess.opts.unstable_opts.min_function_alignment); // Compute the disabled sanitizers. - codegen_fn_attrs.no_sanitize |= tcx.disabled_sanitizers_for(did); + codegen_fn_attrs.sanitizers.disabled |= + tcx.sanitizer_settings_for(did).disabled; // On trait methods, inherit the `#[align]` of the trait's method prototype. codegen_fn_attrs.alignment = Ord::max(codegen_fn_attrs.alignment, tcx.inherited_align(did)); @@ -455,14 +455,14 @@ fn check_result( } // warn that inline has no effect when no_sanitize is present - if !codegen_fn_attrs.no_sanitize.is_empty() + if codegen_fn_attrs.sanitizers != SanitizerFnAttrs::default() && codegen_fn_attrs.inline.always() - && let (Some(no_sanitize_span), Some(inline_span)) = + && 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, no_sanitize_span, |lint| { - lint.primary_message("setting `sanitize` off will have no effect after inlining"); + tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, sanitize_span, |lint| { + lint.primary_message("non-default `sanitize` will have no effect after inlining"); lint.span_note(inline_span, "inlining requested here"); }) } @@ -576,14 +576,14 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { codegen_fn_attrs } -fn disabled_sanitizers_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerSet { +fn sanitizer_settings_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerFnAttrs { // Backtrack to the crate root. - let mut disabled = match tcx.opt_local_parent(did) { + let mut settings = match tcx.opt_local_parent(did) { // Check the parent (recursively). - Some(parent) => tcx.disabled_sanitizers_for(parent), + Some(parent) => tcx.sanitizer_settings_for(parent), // We reached the crate root without seeing an attribute, so // there is no sanitizers to exclude. - None => SanitizerSet::empty(), + None => SanitizerFnAttrs::default(), }; // Check for a sanitize annotation directly on this def. @@ -591,15 +591,15 @@ fn disabled_sanitizers_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerSet { { // the on set is the set of sanitizers explicitly enabled. // we mask those out since we want the set of disabled sanitizers here - disabled &= !*on_set; + settings.disabled &= !*on_set; // the off set is the set of sanitizers explicitly disabled. // we or those in here. - disabled |= *off_set; + settings.disabled |= *off_set; // the on set and off set are distjoint since there's a third option: unset. // a node may not set the sanitizer setting in which case it inherits from parents. // the code above in this function does this backtracking } - disabled + settings } /// Checks if the provided DefId is a method in a trait impl for a trait which has track_caller @@ -731,7 +731,7 @@ pub(crate) fn provide(providers: &mut Providers) { codegen_fn_attrs, should_inherit_track_caller, inherited_align, - disabled_sanitizers_for, + sanitizer_settings_for, ..*providers }; } diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 72786931ff8a..8d4385a2fd32 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -36,6 +36,8 @@ #![feature(box_as_ptr)] #![feature(box_patterns)] #![feature(closure_track_caller)] +#![feature(const_default)] +#![feature(const_trait_impl)] #![feature(core_intrinsics)] #![feature(debug_closure_helpers)] #![feature(decl_macro)] diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index d47d811610a7..fd1f5791de4d 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -80,9 +80,9 @@ pub struct CodegenFnAttrs { /// The `#[link_section = "..."]` attribute, or what executable section this /// should be placed in. pub link_section: Option, - /// The `#[sanitize(xyz = "off")]` attribute. Indicates sanitizers for which - /// instrumentation should be disabled inside the function. - pub no_sanitize: SanitizerSet, + /// The `#[sanitize(xyz = "off")]` attribute. Indicates the settings for each + /// sanitizer for this function. + pub sanitizers: SanitizerFnAttrs, /// The `#[instruction_set(set)]` attribute. Indicates if the generated code should /// be generated against a specific instruction set. Only usable on architectures which allow /// switching between multiple instruction sets. @@ -209,7 +209,7 @@ impl CodegenFnAttrs { linkage: None, import_linkage: None, link_section: None, - no_sanitize: SanitizerSet::empty(), + sanitizers: SanitizerFnAttrs::default(), instruction_set: None, alignment: None, patchable_function_entry: None, @@ -241,3 +241,15 @@ impl CodegenFnAttrs { } } } + +#[derive(Clone, Copy, Debug, HashStable, TyEncodable, TyDecodable, Eq, PartialEq)] +pub struct SanitizerFnAttrs { + pub disabled: SanitizerSet, +} + +impl const Default for SanitizerFnAttrs { + fn default() -> Self { + Self { disabled: SanitizerSet::empty() } + } + +} diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 46100358c7d7..404330a9a45a 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -348,6 +348,7 @@ trivial! { rustc_middle::ty::UnusedGenericParams, rustc_middle::ty::util::AlwaysRequiresDrop, rustc_middle::ty::Visibility, + rustc_middle::middle::codegen_fn_attrs::SanitizerFnAttrs, rustc_session::config::CrateType, rustc_session::config::EntryFnType, rustc_session::config::OptLevel, @@ -365,7 +366,6 @@ trivial! { rustc_span::Symbol, rustc_span::Ident, rustc_target::spec::PanicStrategy, - rustc_target::spec::SanitizerSet, rustc_type_ir::Variance, u32, usize, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index e6bbdc87d995..a2fb797c3f28 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -97,7 +97,7 @@ use rustc_session::lint::LintExpectationId; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, Span, Symbol}; -use rustc_target::spec::{PanicStrategy, SanitizerSet}; +use rustc_target::spec::PanicStrategy; use {rustc_abi as abi, rustc_ast as ast, rustc_hir as hir}; pub use self::keys::{AsLocalKey, Key, LocalCrate}; @@ -105,7 +105,7 @@ pub use self::plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsur use crate::infer::canonical::{self, Canonical}; use crate::lint::LintExpectation; use crate::metadata::ModChild; -use crate::middle::codegen_fn_attrs::CodegenFnAttrs; +use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, SanitizerFnAttrs}; use crate::middle::debugger_visualizer::DebuggerVisualizerFile; use crate::middle::deduced_param_attrs::DeducedParamAttrs; use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; @@ -2735,8 +2735,8 @@ rustc_queries! { /// `#[sanitize(xyz = "on")]` on this def and any enclosing defs, up to the /// crate root. /// - /// Returns the set of sanitizers that is explicitly disabled for this def. - query disabled_sanitizers_for(key: LocalDefId) -> SanitizerSet { + /// Returns the sanitizer settings for this def. + query sanitizer_settings_for(key: LocalDefId) -> SanitizerFnAttrs { desc { |tcx| "checking what set of sanitizers are enabled on `{}`", tcx.def_path_str(key) } feedable } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 7e1dd76f903d..9e3ca9b30d53 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -818,7 +818,7 @@ fn check_codegen_attributes<'tcx, I: Inliner<'tcx>>( } let codegen_fn_attrs = tcx.codegen_fn_attrs(inliner.caller_def_id()); - if callee_attrs.no_sanitize != codegen_fn_attrs.no_sanitize { + if callee_attrs.sanitizers != codegen_fn_attrs.sanitizers { return Err("incompatible sanitizer set"); } diff --git a/tests/ui/sanitizer/inline-always-sanitize.rs b/tests/ui/sanitizer/inline-always-sanitize.rs index d6ee214e9b37..97bb60df72a6 100644 --- a/tests/ui/sanitizer/inline-always-sanitize.rs +++ b/tests/ui/sanitizer/inline-always-sanitize.rs @@ -5,7 +5,7 @@ #[inline(always)] //~^ NOTE inlining requested here #[sanitize(address = "off")] -//~^ WARN setting `sanitize` off will have no effect after inlining +//~^ WARN non-default `sanitize` will have no effect after inlining //~| NOTE on by default fn x() { } diff --git a/tests/ui/sanitizer/inline-always-sanitize.stderr b/tests/ui/sanitizer/inline-always-sanitize.stderr index ed4794721695..fbfe5378c092 100644 --- a/tests/ui/sanitizer/inline-always-sanitize.stderr +++ b/tests/ui/sanitizer/inline-always-sanitize.stderr @@ -1,4 +1,4 @@ -warning: setting `sanitize` off will have no effect after inlining +warning: non-default `sanitize` will have no effect after inlining --> $DIR/inline-always-sanitize.rs:7:1 | LL | #[sanitize(address = "off")]