Skip to content

Commit

Permalink
Rollup merge of #92701 - ehuss:even-more-attr-validation, r=matthewja…
Browse files Browse the repository at this point in the history
…sper

Add some more attribute validation

This adds some more validation for the position of attributes:

* `link` is only valid on an `extern` block
* `windows_subsystem` and `no_builtins` are only valid at the crate level
  • Loading branch information
matthiaskrgr committed Jan 18, 2022
2 parents cb5ecff + b59e743 commit 804072f
Show file tree
Hide file tree
Showing 4 changed files with 350 additions and 163 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,15 +352,15 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[

// Runtime
ungated!(
windows_subsystem, Normal,
windows_subsystem, CrateLevel,
template!(NameValueStr: "windows|console"), FutureWarnFollowing
),
ungated!(panic_handler, Normal, template!(Word), WarnFollowing), // RFC 2070

// Code generation:
ungated!(inline, Normal, template!(Word, List: "always|never"), FutureWarnFollowing),
ungated!(cold, Normal, template!(Word), WarnFollowing),
ungated!(no_builtins, Normal, template!(Word), WarnFollowing),
ungated!(no_builtins, CrateLevel, template!(Word), WarnFollowing),
ungated!(target_feature, Normal, template!(List: r#"enable = "name""#), DuplicatesOk),
ungated!(track_caller, Normal, template!(Word), WarnFollowing),
gated!(
Expand Down
21 changes: 21 additions & 0 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ impl CheckAttrVisitor<'_> {
// lint-only checks
match attr.name_or_empty() {
sym::cold => self.check_cold(hir_id, attr, span, target),
sym::link => self.check_link(hir_id, attr, span, target),
sym::link_name => self.check_link_name(hir_id, attr, span, target),
sym::link_section => self.check_link_section(hir_id, attr, span, target),
sym::no_mangle => self.check_no_mangle(hir_id, attr, span, target),
Expand Down Expand Up @@ -1157,6 +1158,26 @@ impl CheckAttrVisitor<'_> {
}
}

/// Checks if `#[link]` is applied to an item other than a foreign module.
fn check_link(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) {
match target {
Target::ForeignMod => {}
_ => {
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
let mut diag = lint.build("attribute should be applied to an `extern` block");
diag.warn(
"this was previously accepted by the compiler but is \
being phased out; it will become a hard error in \
a future release!",
);

diag.span_label(*span, "not an `extern` block");
diag.emit();
});
}
}
}

/// Checks if `#[link_name]` is applied to an item other than a foreign function or static.
fn check_link_name(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) {
match target {
Expand Down
47 changes: 38 additions & 9 deletions src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//~ NOTE not a function
//~^ NOTE not a foreign function or static
//~^^ NOTE not a function or static
//~| NOTE not a foreign function or static
//~| NOTE not a function or static
//~| NOTE not an `extern` block
// This test enumerates as many compiler-builtin ungated attributes as
// possible (that is, all the mutually compatible ones), and checks
// that we get "expected" (*) warnings for each in the various weird
Expand Down Expand Up @@ -59,9 +60,9 @@
#![proc_macro_derive()] //~ WARN `#[proc_macro_derive]` only has an effect
#![doc = "2400"]
#![cold] //~ WARN attribute should be applied to a function
//~^ WARN
// see issue-43106-gating-of-builtin-attrs-error.rs
#![link()]
//~^ WARN this was previously accepted
#![link()] //~ WARN attribute should be applied to an `extern` block
//~^ WARN this was previously accepted
#![link_name = "1900"]
//~^ WARN attribute should be applied to a foreign function
//~^^ WARN this was previously accepted by the compiler
Expand Down Expand Up @@ -547,22 +548,38 @@ mod link_section {
}


// Note that this is a `check-pass` test, so it
// will never invoke the linker. These are here nonetheless to point
// out that we allow them at non-crate-level (though I do not know
// whether they have the same effect here as at crate-level).
// Note that this is a `check-pass` test, so it will never invoke the linker.

#[link()]
//~^ WARN attribute should be applied to an `extern` block
//~| WARN this was previously accepted
mod link {
//~^ NOTE not an `extern` block

mod inner { #![link()] }
//~^ WARN attribute should be applied to an `extern` block
//~| WARN this was previously accepted
//~| NOTE not an `extern` block

#[link()] fn f() { }
//~^ WARN attribute should be applied to an `extern` block
//~| WARN this was previously accepted
//~| NOTE not an `extern` block

#[link()] struct S;
//~^ WARN attribute should be applied to an `extern` block
//~| WARN this was previously accepted
//~| NOTE not an `extern` block

#[link()] type T = S;
//~^ WARN attribute should be applied to an `extern` block
//~| WARN this was previously accepted
//~| NOTE not an `extern` block

#[link()] impl S { }
//~^ WARN attribute should be applied to an `extern` block
//~| WARN this was previously accepted
//~| NOTE not an `extern` block
}

struct StructForDeprecated;
Expand Down Expand Up @@ -594,16 +611,22 @@ mod must_use {
}

#[windows_subsystem = "windows"]
//~^ WARN crate-level attribute should be an inner attribute
mod windows_subsystem {
mod inner { #![windows_subsystem="windows"] }
//~^ WARN crate-level attribute should be in the root module

#[windows_subsystem = "windows"] fn f() { }
//~^ WARN crate-level attribute should be an inner attribute

#[windows_subsystem = "windows"] struct S;
//~^ WARN crate-level attribute should be an inner attribute

#[windows_subsystem = "windows"] type T = S;
//~^ WARN crate-level attribute should be an inner attribute

#[windows_subsystem = "windows"] impl S { }
//~^ WARN crate-level attribute should be an inner attribute
}

// BROKEN USES OF CRATE-LEVEL BUILT-IN ATTRIBUTES
Expand Down Expand Up @@ -686,16 +709,22 @@ mod no_main_1 {
}

#[no_builtins]
//~^ WARN crate-level attribute should be an inner attribute
mod no_builtins {
mod inner { #![no_builtins] }
//~^ WARN crate-level attribute should be in the root module

#[no_builtins] fn f() { }
//~^ WARN crate-level attribute should be an inner attribute

#[no_builtins] struct S;
//~^ WARN crate-level attribute should be an inner attribute

#[no_builtins] type T = S;
//~^ WARN crate-level attribute should be an inner attribute

#[no_builtins] impl S { }
//~^ WARN crate-level attribute should be an inner attribute
}

#[recursion_limit="0200"]
Expand Down
Loading

0 comments on commit 804072f

Please sign in to comment.