1
Fork 0

switch to an allowlist approach

- merge error codes
- use attribute name that is incompatible in error message
- add test for conditional incompatible attribute
- add `linkage` to the allowlist
This commit is contained in:
Folkert 2024-07-17 10:42:24 +02:00
parent 4d082b77af
commit c6a166bac2
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
16 changed files with 185 additions and 65 deletions

View file

@ -418,17 +418,53 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
target: Target,
attrs: &[Attribute],
) -> bool {
const FORBIDDEN: [rustc_span::Symbol; 3] =
[sym::track_caller, sym::inline, sym::target_feature];
// many attributes don't make sense in combination with #[naked].
// Notable attributes that are incompatible with `#[naked]` are:
//
// * `#[inline]`
// * `#[track_caller]`
// * `#[target_feature]`
// * `#[test]`, `#[ignore]`, `#[should_panic]`
//
// NOTE: when making changes to this list, check that `error_codes/E0736.md` remains accurate
const ALLOW_LIST: &[rustc_span::Symbol] = &[
// conditional compilation
sym::cfg,
sym::cfg_attr,
// testing (allowed here so better errors can be generated in `rustc_builtin_macros::test`)
sym::test,
sym::ignore,
sym::should_panic,
sym::bench,
// diagnostics
sym::allow,
sym::warn,
sym::deny,
sym::forbid,
sym::deprecated,
sym::must_use,
// abi, linking and FFI
sym::export_name,
sym::link_section,
sym::linkage,
sym::no_mangle,
sym::naked,
sym::instruction_set,
// code generation
sym::cold,
// documentation
sym::doc,
];
match target {
Target::Fn
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {
for other_attr in attrs {
if FORBIDDEN.into_iter().any(|name| other_attr.has_name(name)) {
self.dcx().emit_err(errors::NakedFunctionCodegenAttribute {
if !ALLOW_LIST.iter().any(|name| other_attr.has_name(*name)) {
self.dcx().emit_err(errors::NakedFunctionIncompatibleAttribute {
span: other_attr.span,
naked_span: attr.span,
attr: other_attr.name_or_empty(),
});
return false;

View file

@ -1183,13 +1183,14 @@ pub struct NakedFunctionsMustUseNoreturn {
}
#[derive(Diagnostic)]
#[diag(passes_naked_functions_codegen_attribute, code = E0736)]
pub struct NakedFunctionCodegenAttribute {
#[diag(passes_naked_functions_incompatible_attribute, code = E0736)]
pub struct NakedFunctionIncompatibleAttribute {
#[primary_span]
#[label]
pub span: Span,
#[label(passes_naked_attribute)]
pub naked_span: Span,
pub attr: Symbol,
}
#[derive(Diagnostic)]