Skip to content

Commit c832971

Browse files
authored
Rollup merge of #157332 - JonathanBrouwer:target-sanitize, r=mejrs
Rewrite target checking for `#[sanitize]` r? @mejrs
2 parents 80c5ad6 + 97dc1b1 commit c832971

17 files changed

Lines changed: 199 additions & 247 deletions

compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::attributes::AttributeSafety;
88
use crate::session_diagnostics::{
99
EmptyExportName, NakedFunctionIncompatibleAttribute, NullOnExport, NullOnObjcClass,
1010
NullOnObjcSelector, ObjcClassExpectedStringLiteral, ObjcSelectorExpectedStringLiteral,
11+
SanitizeInvalidStatic,
1112
};
1213
use crate::target_checking::Policy::AllowSilent;
1314

@@ -566,8 +567,18 @@ pub(crate) struct SanitizeParser;
566567

567568
impl SingleAttributeParser for SanitizeParser {
568569
const PATH: &[Symbol] = &[sym::sanitize];
569-
// FIXME: still checked in check_attrs.rs
570-
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
570+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
571+
Allow(Target::Fn),
572+
Allow(Target::Closure),
573+
Allow(Target::Method(MethodKind::Inherent)),
574+
Allow(Target::Method(MethodKind::Trait { body: true })),
575+
Allow(Target::Method(MethodKind::TraitImpl)),
576+
Allow(Target::Impl { of_trait: false }),
577+
Allow(Target::Impl { of_trait: true }),
578+
Allow(Target::Mod),
579+
Allow(Target::Crate),
580+
Allow(Target::Static),
581+
]);
571582
const TEMPLATE: AttributeTemplate = template!(List: &[
572583
r#"address = "on|off""#,
573584
r#"kernel_address = "on|off""#,
@@ -668,6 +679,18 @@ impl SingleAttributeParser for SanitizeParser {
668679
}
669680
}
670681

682+
// The sanitizer attribute is only allowed on statics, if only address bits are set
683+
let all_set_except_address =
684+
(on_set | off_set) & !(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS);
685+
if cx.target == Target::Static
686+
&& let Some(set) = all_set_except_address.iter().next()
687+
{
688+
cx.emit_err(SanitizeInvalidStatic {
689+
span: cx.attr_span,
690+
field: set.as_str().expect("Since this `SanitizerSet` is returned from an iterator, exactly one field is set")
691+
});
692+
}
693+
671694
Some(AttributeKind::Sanitize { on_set, off_set, rtsan, span: cx.attr_span })
672695
}
673696
}

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,3 +1023,12 @@ pub(crate) enum InvalidMachoSectionReason {
10231023
#[note("section name `{$section}` is longer than 16 bytes")]
10241024
SectionTooLong { section: String },
10251025
}
1026+
1027+
#[derive(Diagnostic)]
1028+
#[diag("`#[sanitize({$field} = ...)]` attribute cannot be used on statics")]
1029+
#[help("`#[sanitize]` can be used on statics if only the address is sanitized")]
1030+
pub(crate) struct SanitizeInvalidStatic {
1031+
#[primary_span]
1032+
pub span: Span,
1033+
pub field: &'static str,
1034+
}

compiler/rustc_attr_parsing/src/target_checking.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,13 @@ pub(crate) fn allowed_targets_applied(
361361
Target::Method(MethodKind::Trait { body: true }),
362362
Target::Method(MethodKind::TraitImpl),
363363
];
364+
const FUNCTION_WITH_BODY_LIKE: &[Target] = &[
365+
Target::Fn,
366+
Target::Closure,
367+
Target::Method(MethodKind::Inherent),
368+
Target::Method(MethodKind::Trait { body: true }),
369+
Target::Method(MethodKind::TraitImpl),
370+
];
364371
const METHOD_LIKE: &[Target] = &[
365372
Target::Method(MethodKind::Inherent),
366373
Target::Method(MethodKind::Trait { body: false }),
@@ -379,6 +386,13 @@ pub(crate) fn allowed_targets_applied(
379386
target,
380387
&mut added_fake_targets,
381388
);
389+
filter_targets(
390+
&mut allowed_targets,
391+
FUNCTION_WITH_BODY_LIKE,
392+
"functions with a body",
393+
target,
394+
&mut added_fake_targets,
395+
);
382396
filter_targets(&mut allowed_targets, METHOD_LIKE, "methods", target, &mut added_fake_targets);
383397
filter_targets(&mut allowed_targets, IMPL_LIKE, "impl blocks", target, &mut added_fake_targets);
384398
filter_targets(&mut allowed_targets, ADT_LIKE, "data types", target, &mut added_fake_targets);

compiler/rustc_passes/src/check_attr.rs

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc_feature::BUILTIN_ATTRIBUTE_MAP;
1818
use rustc_hir::attrs::diagnostic::Directive;
1919
use rustc_hir::attrs::{
2020
AttributeKind, DocAttribute, DocInline, EiiDecl, EiiImpl, EiiImplResolution, InlineAttr,
21-
ReprAttr, SanitizerSet,
21+
ReprAttr,
2222
};
2323
use rustc_hir::def::DefKind;
2424
use rustc_hir::def_id::LocalModDefId;
@@ -227,9 +227,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
227227
}
228228
&AttributeKind::FfiPure(attr_span) => self.check_ffi_pure(attr_span, attrs),
229229
AttributeKind::MayDangle(attr_span) => self.check_may_dangle(hir_id, *attr_span),
230-
&AttributeKind::Sanitize { on_set, off_set, rtsan: _, span: attr_span } => {
231-
self.check_sanitize(attr_span, on_set | off_set, span, target);
232-
}
233230
AttributeKind::Link(_, attr_span) => self.check_link(hir_id, *attr_span, target),
234231
AttributeKind::MacroExport { span, .. } => {
235232
self.check_macro_export(hir_id, *span, target)
@@ -401,6 +398,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
401398
AttributeKind::RustcThenThisWouldNeed(..) => (),
402399
AttributeKind::RustcTrivialFieldReads => (),
403400
AttributeKind::RustcUnsafeSpecializationMarker => (),
401+
AttributeKind::Sanitize { .. } => {}
404402
AttributeKind::ShouldPanic { .. } => (),
405403
AttributeKind::Stability { .. } => (),
406404
AttributeKind::TestRunner(..) => (),
@@ -627,52 +625,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
627625
}
628626
}
629627

630-
/// Checks that the `#[sanitize(..)]` attribute is applied to a
631-
/// function/closure/method, or to an impl block or module.
632-
fn check_sanitize(
633-
&self,
634-
attr_span: Span,
635-
set: SanitizerSet,
636-
target_span: Span,
637-
target: Target,
638-
) {
639-
let mut not_fn_impl_mod = None;
640-
let mut no_body = None;
641-
642-
match target {
643-
Target::Fn
644-
| Target::Closure
645-
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent)
646-
| Target::Impl { .. }
647-
| Target::Mod => return,
648-
Target::Static
649-
// if we mask out the address bits, i.e. *only* address was set,
650-
// we allow it
651-
if set & !(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS)
652-
== SanitizerSet::empty() =>
653-
{
654-
return;
655-
}
656-
657-
// These are "functions", but they aren't allowed because they don't
658-
// have a body, so the usual explanation would be confusing.
659-
Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => {
660-
no_body = Some(target_span);
661-
}
662-
663-
_ => {
664-
not_fn_impl_mod = Some(target_span);
665-
}
666-
}
667-
668-
self.dcx().emit_err(errors::SanitizeAttributeNotAllowed {
669-
attr_span,
670-
not_fn_impl_mod,
671-
no_body,
672-
help: (),
673-
});
674-
}
675-
676628
/// Checks if `#[naked]` is applied to a function definition.
677629
fn check_naked(&self, hir_id: HirId, target: Target) {
678630
match target {

compiler/rustc_passes/src/errors.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,19 +1049,6 @@ pub(crate) struct UnnecessaryPartialStableFeature {
10491049
#[note("see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information")]
10501050
pub(crate) struct IneffectiveUnstableImpl;
10511051

1052-
#[derive(Diagnostic)]
1053-
#[diag("sanitize attribute not allowed here")]
1054-
pub(crate) struct SanitizeAttributeNotAllowed {
1055-
#[primary_span]
1056-
pub attr_span: Span,
1057-
#[label("not a function, impl block, or module")]
1058-
pub not_fn_impl_mod: Option<Span>,
1059-
#[label("function has no body")]
1060-
pub no_body: Option<Span>,
1061-
#[help("sanitize attribute can be applied to a function (with body), impl block, or module")]
1062-
pub help: (),
1063-
}
1064-
10651052
// FIXME(jdonszelmann): move back to rustc_attr
10661053
#[derive(Diagnostic)]
10671054
#[diag(

tests/ui/asm/naked-invalid-attr.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ error: `#[naked]` attribute cannot be used on foreign functions
1818
LL | #[unsafe(naked)]
1919
| ^^^^^^^^^^^^^^^^
2020
|
21-
= help: `#[naked]` can be applied to functions and methods
21+
= help: `#[naked]` can only be applied to functions with a body
2222

2323
error: `#[naked]` attribute cannot be used on structs
2424
--> $DIR/naked-invalid-attr.rs:14:1
@@ -42,7 +42,7 @@ error: `#[naked]` attribute cannot be used on required trait methods
4242
LL | #[unsafe(naked)]
4343
| ^^^^^^^^^^^^^^^^
4444
|
45-
= help: `#[naked]` can be applied to functions, inherent methods, provided trait methods, and trait methods in impl blocks
45+
= help: `#[naked]` can only be applied to functions with a body
4646

4747
error: `#[naked]` attribute cannot be used on closures
4848
--> $DIR/naked-invalid-attr.rs:52:5

tests/ui/attributes/attr-on-mac-call.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
//@ check-pass
1+
//@ check-fail
22
// Regression test for https://github.com/rust-lang/rust/issues/145779
33
#![warn(unused_attributes)]
4+
#![feature(sanitize)]
45

56
fn main() {
67
#[export_name = "x"]
@@ -72,6 +73,8 @@ fn main() {
7273
#[link_name = "x"]
7374
//~^ WARN attribute cannot be used on macro calls
7475
//~| WARN previously accepted
76+
#[sanitize(address = "off")]
77+
//~^ ERROR attribute cannot be used on macro calls
7578
unreachable!();
7679

7780
#[repr()]

0 commit comments

Comments
 (0)