Skip to content

Commit 821905c

Browse files
committed
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.
1 parent 3fa6cc1 commit 821905c

38 files changed

+226
-404
lines changed

compiler/rustc_codegen_ssa/messages.ftl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,8 @@ codegen_ssa_invalid_monomorphization_unsupported_symbol = invalid monomorphizati
169169
170170
codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size = invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` of size `{$size}` to `{$ret_ty}`
171171
172-
codegen_ssa_invalid_no_sanitize = invalid argument for `no_sanitize`
173-
.note = expected one of: `address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow-call-stack`, or `thread`
174-
175172
codegen_ssa_invalid_sanitize = invalid argument for `sanitize`
176-
.note = expected one of: `address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow-call-stack`, or `thread`
173+
.note = expected one of: `address`, `kernel_address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow_call_stack`, or `thread`
177174
178175
codegen_ssa_invalid_windows_subsystem = invalid windows subsystem `{$subsystem}`, only `windows` and `console` are allowed
179176

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 22 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -110,32 +110,6 @@ fn parse_linkage_attr(tcx: TyCtxt<'_>, did: LocalDefId, attr: &Attribute) -> Opt
110110
Some(linkage)
111111
}
112112

113-
// FIXME(jdonszelmann): remove when no_sanitize becomes a parsed attr
114-
fn parse_no_sanitize_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> Option<SanitizerSet> {
115-
let list = attr.meta_item_list()?;
116-
let mut sanitizer_set = SanitizerSet::empty();
117-
118-
for item in list.iter() {
119-
match item.name() {
120-
Some(sym::address) => {
121-
sanitizer_set |= SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS
122-
}
123-
Some(sym::cfi) => sanitizer_set |= SanitizerSet::CFI,
124-
Some(sym::kcfi) => sanitizer_set |= SanitizerSet::KCFI,
125-
Some(sym::memory) => sanitizer_set |= SanitizerSet::MEMORY,
126-
Some(sym::memtag) => sanitizer_set |= SanitizerSet::MEMTAG,
127-
Some(sym::shadow_call_stack) => sanitizer_set |= SanitizerSet::SHADOWCALLSTACK,
128-
Some(sym::thread) => sanitizer_set |= SanitizerSet::THREAD,
129-
Some(sym::hwaddress) => sanitizer_set |= SanitizerSet::HWADDRESS,
130-
_ => {
131-
tcx.dcx().emit_err(errors::InvalidNoSanitize { span: item.span() });
132-
}
133-
}
134-
}
135-
136-
Some(sanitizer_set)
137-
}
138-
139113
// FIXME(jdonszelmann): remove when patchable_function_entry becomes a parsed attr
140114
fn parse_patchable_function_entry(
141115
tcx: TyCtxt<'_>,
@@ -194,7 +168,6 @@ fn parse_patchable_function_entry(
194168
#[derive(Default)]
195169
struct InterestingAttributeDiagnosticSpans {
196170
link_ordinal: Option<Span>,
197-
no_sanitize: Option<Span>,
198171
sanitize: Option<Span>,
199172
inline: Option<Span>,
200173
no_mangle: Option<Span>,
@@ -372,11 +345,6 @@ fn process_builtin_attrs(
372345
codegen_fn_attrs.linkage = linkage;
373346
}
374347
}
375-
sym::no_sanitize => {
376-
interesting_spans.no_sanitize = Some(attr.span());
377-
codegen_fn_attrs.no_sanitize |=
378-
parse_no_sanitize_attr(tcx, attr).unwrap_or_default();
379-
}
380348
sym::sanitize => interesting_spans.sanitize = Some(attr.span()),
381349
sym::instruction_set => {
382350
codegen_fn_attrs.instruction_set = parse_instruction_set_attr(tcx, attr)
@@ -479,24 +447,14 @@ fn check_result(
479447
if !codegen_fn_attrs.no_sanitize.is_empty()
480448
&& codegen_fn_attrs.inline.always()
481449
&& let (Some(no_sanitize_span), Some(inline_span)) =
482-
(interesting_spans.no_sanitize, interesting_spans.inline)
450+
(interesting_spans.sanitize, interesting_spans.inline)
483451
{
484452
let hir_id = tcx.local_def_id_to_hir_id(did);
485453
tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, no_sanitize_span, |lint| {
486454
lint.primary_message("`no_sanitize` will have no effect after inlining");
487455
lint.span_note(inline_span, "inlining requested here");
488456
})
489457
}
490-
if !codegen_fn_attrs.no_sanitize.is_empty()
491-
&& codegen_fn_attrs.inline.always()
492-
&& let (Some(sanitize_span), Some(inline_span)) = (interesting_spans.sanitize, interesting_spans.inline)
493-
{
494-
let hir_id = tcx.local_def_id_to_hir_id(did);
495-
tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, sanitize_span, |lint| {
496-
lint.primary_message("setting `sanitize` off will have no effect after inlining");
497-
lint.span_note(inline_span, "inlining requested here");
498-
})
499-
}
500458

501459
// error when specifying link_name together with link_ordinal
502460
if let Some(_) = codegen_fn_attrs.link_name
@@ -620,9 +578,14 @@ fn opt_trait_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
620578
}
621579

622580
/// For an attr that has the `sanitize` attribute, read the list of
623-
/// disabled sanitizers.
624-
fn parse_sanitize_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> SanitizerSet {
625-
let mut result = SanitizerSet::empty();
581+
/// disabled sanitizers. `current_attr` holds the information about
582+
/// previously parsed attributes.
583+
fn parse_sanitize_attr(
584+
tcx: TyCtxt<'_>,
585+
attr: &Attribute,
586+
current_attr: SanitizerSet,
587+
) -> SanitizerSet {
588+
let mut result = current_attr;
626589
if let Some(list) = attr.meta_item_list() {
627590
for item in list.iter() {
628591
let MetaItemInner::MetaItem(set) = item else {
@@ -631,10 +594,13 @@ fn parse_sanitize_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> SanitizerSet {
631594
};
632595
let segments = set.path.segments.iter().map(|x| x.ident.name).collect::<Vec<_>>();
633596
match segments.as_slice() {
634-
[sym::address] if set.value_str() == Some(sym::off) => {
597+
// Similar to clang, sanitize(address = ..) and
598+
// sanitize(kernel_address = ..) control both ASan and KASan
599+
// Source: https://reviews.llvm.org/D44981.
600+
[sym::address] | [sym::kernel_address] if set.value_str() == Some(sym::off) => {
635601
result |= SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS
636602
}
637-
[sym::address] if set.value_str() == Some(sym::on) => {
603+
[sym::address] | [sym::kernel_address] if set.value_str() == Some(sym::on) => {
638604
result &= !SanitizerSet::ADDRESS;
639605
result &= !SanitizerSet::KERNELADDRESS;
640606
}
@@ -682,19 +648,20 @@ fn parse_sanitize_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> SanitizerSet {
682648
}
683649

684650
fn disabled_sanitizers_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerSet {
685-
// Check for a sanitize annotation directly on this def.
686-
if let Some(attr) = tcx.get_attr(did, sym::sanitize) {
687-
return parse_sanitize_attr(tcx, attr);
688-
}
689-
690-
// Otherwise backtrack.
691-
match tcx.opt_local_parent(did) {
651+
// Backtrack to the crate root.
652+
let disabled = match tcx.opt_local_parent(did) {
692653
// Check the parent (recursively).
693654
Some(parent) => tcx.disabled_sanitizers_for(parent),
694655
// We reached the crate root without seeing an attribute, so
695656
// there is no sanitizers to exclude.
696657
None => SanitizerSet::empty(),
658+
};
659+
660+
// Check for a sanitize annotation directly on this def.
661+
if let Some(attr) = tcx.get_attr(did, sym::sanitize) {
662+
return parse_sanitize_attr(tcx, attr, disabled);
697663
}
664+
disabled
698665
}
699666

700667
/// Checks if the provided DefId is a method in a trait impl for a trait which has track_caller

compiler/rustc_codegen_ssa/src/errors.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,14 +1100,6 @@ impl IntoDiagArg for ExpectedPointerMutability {
11001100
}
11011101
}
11021102

1103-
#[derive(Diagnostic)]
1104-
#[diag(codegen_ssa_invalid_no_sanitize)]
1105-
#[note]
1106-
pub(crate) struct InvalidNoSanitize {
1107-
#[primary_span]
1108-
pub span: Span,
1109-
}
1110-
11111103
#[derive(Diagnostic)]
11121104
#[diag(codegen_ssa_invalid_sanitize)]
11131105
#[note]

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -540,11 +540,6 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
540540
),
541541
ungated!(track_caller, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes),
542542
ungated!(instruction_set, Normal, template!(List: "set"), ErrorPreceding, EncodeCrossCrate::No),
543-
gated!(
544-
no_sanitize, Normal,
545-
template!(List: "address, kcfi, memory, thread"), DuplicatesOk,
546-
EncodeCrossCrate::No, experimental!(no_sanitize)
547-
),
548543
gated!(
549544
sanitize, Normal, template!(List: r#"address = "on|off", cfi = "on|off""#), ErrorPreceding,
550545
EncodeCrossCrate::No, sanitize, experimental!(sanitize),

compiler/rustc_feature/src/removed.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ declare_features! (
190190
(removed, no_coverage, "1.74.0", Some(84605), Some("renamed to `coverage_attribute`"), 114656),
191191
/// Allows `#[no_debug]`.
192192
(removed, no_debug, "1.43.0", Some(29721), Some("removed due to lack of demand"), 69667),
193+
// Allows the use of `no_sanitize` attribute.
194+
/// The feature was renamed to `sanitize` and the attribute to `#[sanitize(xyz = "on|off")]`
195+
(removed, no_sanitize, "CURRENT_RUSTC_VERSION", Some(39699), Some(r#"renamed to sanitize(xyz = "on|off")"#), 142681),
193196
/// Note: this feature was previously recorded in a separate
194197
/// `STABLE_REMOVED` list because it, uniquely, was once stable but was
195198
/// then removed. But there was no utility storing it separately, so now

compiler/rustc_feature/src/unstable.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,8 +589,6 @@ declare_features! (
589589
(unstable, new_range, "1.86.0", Some(123741)),
590590
/// Allows `#![no_core]`.
591591
(unstable, no_core, "1.3.0", Some(29639)),
592-
/// Allows the use of `no_sanitize` attribute.
593-
(unstable, no_sanitize, "1.42.0", Some(39699)),
594592
/// Allows using the `non_exhaustive_omitted_patterns` lint.
595593
(unstable, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554)),
596594
/// Allows `for<T>` binders in where-clauses

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2299,18 +2299,18 @@ declare_lint! {
22992299

23002300
declare_lint! {
23012301
/// The `inline_no_sanitize` lint detects incompatible use of
2302-
/// [`#[inline(always)]`][inline] and [`#[no_sanitize(...)]`][no_sanitize].
2302+
/// [`#[inline(always)]`][inline] and [`#[sanitize(xyz = "off")]`][sanitize].
23032303
///
23042304
/// [inline]: https://doc.rust-lang.org/reference/attributes/codegen.html#the-inline-attribute
2305-
/// [no_sanitize]: https://doc.rust-lang.org/nightly/unstable-book/language-features/no-sanitize.html
2305+
/// [sanitize]: https://doc.rust-lang.org/nightly/unstable-book/language-features/no-sanitize.html
23062306
///
23072307
/// ### Example
23082308
///
23092309
/// ```rust
2310-
/// #![feature(no_sanitize)]
2310+
/// #![feature(sanitize)]
23112311
///
23122312
/// #[inline(always)]
2313-
/// #[no_sanitize(address)]
2313+
/// #[sanitize(address = "off")]
23142314
/// fn x() {}
23152315
///
23162316
/// fn main() {
@@ -2323,11 +2323,11 @@ declare_lint! {
23232323
/// ### Explanation
23242324
///
23252325
/// The use of the [`#[inline(always)]`][inline] attribute prevents the
2326-
/// the [`#[no_sanitize(...)]`][no_sanitize] attribute from working.
2326+
/// the [`#[sanitize(xyz = "off")]`][sanitize] attribute from working.
23272327
/// Consider temporarily removing `inline` attribute.
23282328
pub INLINE_NO_SANITIZE,
23292329
Warn,
2330-
"detects incompatible use of `#[inline(always)]` and `#[no_sanitize(...)]`",
2330+
r#"detects incompatible use of `#[inline(always)]` and `#[sanitize(... = "off")]`"#,
23312331
}
23322332

23332333
declare_lint! {

compiler/rustc_middle/src/middle/codegen_fn_attrs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ pub struct CodegenFnAttrs {
6262
/// The `#[link_section = "..."]` attribute, or what executable section this
6363
/// should be placed in.
6464
pub link_section: Option<Symbol>,
65-
/// The `#[no_sanitize(...)]` attribute. Indicates sanitizers for which
66-
/// instrumentation should be disabled inside the annotated function.
65+
/// The `#[sanitize(xyz = "off")]` attribute. Indicates sanitizers for which
66+
/// instrumentation should be disabled inside the function.
6767
pub no_sanitize: SanitizerSet,
6868
/// The `#[instruction_set(set)]` attribute. Indicates if the generated code should
6969
/// be generated against a specific instruction set. Only usable on architectures which allow

compiler/rustc_passes/messages.ftl

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -541,10 +541,6 @@ passes_no_mangle_foreign =
541541
.note = symbol names in extern blocks are not mangled
542542
.suggestion = remove this attribute
543543
544-
passes_no_sanitize =
545-
`#[no_sanitize({$attr_str})]` should be applied to {$accepted_kind}
546-
.label = not {$accepted_kind}
547-
548544
passes_non_exhaustive_with_default_field_values =
549545
`#[non_exhaustive]` can't be used to annotate items with default field values
550546
.label = this struct has default field values

compiler/rustc_passes/src/check_attr.rs

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
333333
[sym::diagnostic, sym::on_unimplemented, ..] => {
334334
self.check_diagnostic_on_unimplemented(attr.span(), hir_id, target)
335335
}
336-
[sym::no_sanitize, ..] => {
337-
self.check_no_sanitize(attr, span, target)
338-
}
339336
[sym::sanitize, ..] => {
340337
self.check_sanitize(attr, span, target)
341338
}
@@ -661,42 +658,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
661658
}
662659
}
663660

664-
fn check_no_sanitize(&self, attr: &Attribute, span: Span, target: Target) {
665-
if let Some(list) = attr.meta_item_list() {
666-
for item in list.iter() {
667-
let sym = item.name();
668-
match sym {
669-
Some(s @ sym::address | s @ sym::hwaddress) => {
670-
let is_valid =
671-
matches!(target, Target::Fn | Target::Method(..) | Target::Static);
672-
if !is_valid {
673-
self.dcx().emit_err(errors::NoSanitize {
674-
attr_span: item.span(),
675-
defn_span: span,
676-
accepted_kind: "a function or static",
677-
attr_str: s.as_str(),
678-
});
679-
}
680-
}
681-
_ => {
682-
let is_valid = matches!(target, Target::Fn | Target::Method(..));
683-
if !is_valid {
684-
self.dcx().emit_err(errors::NoSanitize {
685-
attr_span: item.span(),
686-
defn_span: span,
687-
accepted_kind: "a function",
688-
attr_str: &match sym {
689-
Some(name) => name.to_string(),
690-
None => "...".to_string(),
691-
},
692-
});
693-
}
694-
}
695-
}
696-
}
697-
}
698-
}
699-
700661
/// Checks that the `#[sanitize(..)]` attribute is applied to a
701662
/// function/closure/method, or to an impl block or module.
702663
fn check_sanitize(&self, attr: &Attribute, target_span: Span, target: Target) {

0 commit comments

Comments
 (0)