mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 22:41:50 +00:00
Rollup merge of #109088 - Nilstrieb:target-feature-on-statics-when, r=compiler-errors
Gracefully handle `#[target_feature]` on statics The was careful around not calling `fn_sig` on not-functions but well, it wasn't careful enough. This commit makes it a little more careful and also adds tests for a bunch more item kinds. I was sadly not able to fully bless the test locally because I'm on an aarch64 machine but I hope some manual editing made it work 😅 Fix #109079
This commit is contained in:
commit
30cd4b3a16
@ -61,25 +61,29 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
|
|||||||
|
|
||||||
let supported_target_features = tcx.supported_target_features(LOCAL_CRATE);
|
let supported_target_features = tcx.supported_target_features(LOCAL_CRATE);
|
||||||
|
|
||||||
// In some cases, attribute are only valid on functions, but it's the `check_attr`
|
|
||||||
// pass that check that they aren't used anywhere else, rather this module.
|
|
||||||
// In these cases, we bail from performing further checks that are only meaningful for
|
|
||||||
// functions (such as calling `fn_sig`, which ICEs if given a non-function). We also
|
|
||||||
// report a delayed bug, just in case `check_attr` isn't doing its job.
|
|
||||||
let validate_fn_only_attr = |attr_sp| -> bool {
|
|
||||||
let def_kind = tcx.def_kind(did);
|
|
||||||
if let DefKind::Fn | DefKind::AssocFn | DefKind::Variant | DefKind::Ctor(..) = def_kind {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
tcx.sess.delay_span_bug(attr_sp, "this attribute can only be applied to functions");
|
|
||||||
false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut inline_span = None;
|
let mut inline_span = None;
|
||||||
let mut link_ordinal_span = None;
|
let mut link_ordinal_span = None;
|
||||||
let mut no_sanitize_span = None;
|
let mut no_sanitize_span = None;
|
||||||
|
|
||||||
for attr in attrs.iter() {
|
for attr in attrs.iter() {
|
||||||
|
// In some cases, attribute are only valid on functions, but it's the `check_attr`
|
||||||
|
// pass that check that they aren't used anywhere else, rather this module.
|
||||||
|
// In these cases, we bail from performing further checks that are only meaningful for
|
||||||
|
// functions (such as calling `fn_sig`, which ICEs if given a non-function). We also
|
||||||
|
// report a delayed bug, just in case `check_attr` isn't doing its job.
|
||||||
|
let fn_sig = || {
|
||||||
|
use DefKind::*;
|
||||||
|
|
||||||
|
let def_kind = tcx.def_kind(did);
|
||||||
|
if let Fn | AssocFn | Variant | Ctor(..) = def_kind {
|
||||||
|
Some(tcx.fn_sig(did))
|
||||||
|
} else {
|
||||||
|
tcx.sess
|
||||||
|
.delay_span_bug(attr.span, "this attribute can only be applied to functions");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if attr.has_name(sym::cold) {
|
if attr.has_name(sym::cold) {
|
||||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD;
|
codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD;
|
||||||
} else if attr.has_name(sym::rustc_allocator) {
|
} else if attr.has_name(sym::rustc_allocator) {
|
||||||
@ -169,8 +173,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if attr.has_name(sym::cmse_nonsecure_entry) {
|
} else if attr.has_name(sym::cmse_nonsecure_entry) {
|
||||||
if validate_fn_only_attr(attr.span)
|
if let Some(fn_sig) = fn_sig()
|
||||||
&& !matches!(tcx.fn_sig(did).skip_binder().abi(), abi::Abi::C { .. })
|
&& !matches!(fn_sig.skip_binder().abi(), abi::Abi::C { .. })
|
||||||
{
|
{
|
||||||
struct_span_err!(
|
struct_span_err!(
|
||||||
tcx.sess,
|
tcx.sess,
|
||||||
@ -189,8 +193,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
|
|||||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
|
codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
|
||||||
} else if attr.has_name(sym::track_caller) {
|
} else if attr.has_name(sym::track_caller) {
|
||||||
if !tcx.is_closure(did.to_def_id())
|
if !tcx.is_closure(did.to_def_id())
|
||||||
&& validate_fn_only_attr(attr.span)
|
&& let Some(fn_sig) = fn_sig()
|
||||||
&& tcx.fn_sig(did).skip_binder().abi() != abi::Abi::Rust
|
&& fn_sig.skip_binder().abi() != abi::Abi::Rust
|
||||||
{
|
{
|
||||||
struct_span_err!(tcx.sess, attr.span, E0737, "`#[track_caller]` requires Rust ABI")
|
struct_span_err!(tcx.sess, attr.span, E0737, "`#[track_caller]` requires Rust ABI")
|
||||||
.emit();
|
.emit();
|
||||||
@ -222,7 +226,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
|
|||||||
}
|
}
|
||||||
} else if attr.has_name(sym::target_feature) {
|
} else if attr.has_name(sym::target_feature) {
|
||||||
if !tcx.is_closure(did.to_def_id())
|
if !tcx.is_closure(did.to_def_id())
|
||||||
&& tcx.fn_sig(did).skip_binder().unsafety() == hir::Unsafety::Normal
|
&& let Some(fn_sig) = fn_sig()
|
||||||
|
&& fn_sig.skip_binder().unsafety() == hir::Unsafety::Normal
|
||||||
{
|
{
|
||||||
if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc {
|
if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc {
|
||||||
// The `#[target_feature]` attribute is allowed on
|
// The `#[target_feature]` attribute is allowed on
|
||||||
|
@ -14,6 +14,21 @@
|
|||||||
|
|
||||||
#![warn(unused_attributes)]
|
#![warn(unused_attributes)]
|
||||||
|
|
||||||
|
#[target_feature(enable = "sse2")]
|
||||||
|
//~^ ERROR attribute should be applied to a function
|
||||||
|
extern crate alloc;
|
||||||
|
//~^ NOTE not a function
|
||||||
|
|
||||||
|
#[target_feature(enable = "sse2")]
|
||||||
|
//~^ ERROR attribute should be applied to a function
|
||||||
|
use alloc::alloc::alloc;
|
||||||
|
//~^ NOTE not a function
|
||||||
|
|
||||||
|
#[target_feature(enable = "sse2")]
|
||||||
|
//~^ ERROR attribute should be applied to a function
|
||||||
|
extern "Rust" {}
|
||||||
|
//~^ NOTE not a function
|
||||||
|
|
||||||
#[target_feature = "+sse2"]
|
#[target_feature = "+sse2"]
|
||||||
//~^ ERROR malformed `target_feature` attribute
|
//~^ ERROR malformed `target_feature` attribute
|
||||||
#[target_feature(enable = "foo")]
|
#[target_feature(enable = "foo")]
|
||||||
@ -59,6 +74,11 @@ union Qux {
|
|||||||
f2: u16,
|
f2: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[target_feature(enable = "sse2")]
|
||||||
|
//~^ ERROR attribute should be applied to a function
|
||||||
|
type Uwu = ();
|
||||||
|
//~^ NOTE not a function
|
||||||
|
|
||||||
#[target_feature(enable = "sse2")]
|
#[target_feature(enable = "sse2")]
|
||||||
//~^ ERROR attribute should be applied to a function
|
//~^ ERROR attribute should be applied to a function
|
||||||
trait Baz {}
|
trait Baz {}
|
||||||
@ -69,6 +89,21 @@ trait Baz {}
|
|||||||
#[target_feature(enable = "sse2")]
|
#[target_feature(enable = "sse2")]
|
||||||
unsafe fn test() {}
|
unsafe fn test() {}
|
||||||
|
|
||||||
|
#[target_feature(enable = "sse2")]
|
||||||
|
//~^ ERROR attribute should be applied to a function
|
||||||
|
static A: () = ();
|
||||||
|
//~^ NOTE not a function
|
||||||
|
|
||||||
|
#[target_feature(enable = "sse2")]
|
||||||
|
//~^ ERROR attribute should be applied to a function
|
||||||
|
impl Quux for u8 {}
|
||||||
|
//~^ NOTE not a function
|
||||||
|
|
||||||
|
#[target_feature(enable = "sse2")]
|
||||||
|
//~^ ERROR attribute should be applied to a function
|
||||||
|
impl Foo {}
|
||||||
|
//~^ NOTE not a function
|
||||||
|
|
||||||
trait Quux {
|
trait Quux {
|
||||||
fn foo();
|
fn foo();
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,38 @@
|
|||||||
error: malformed `target_feature` attribute input
|
error: malformed `target_feature` attribute input
|
||||||
--> $DIR/invalid-attribute.rs:17:1
|
--> $DIR/invalid-attribute.rs:32:1
|
||||||
|
|
|
|
||||||
LL | #[target_feature = "+sse2"]
|
LL | #[target_feature = "+sse2"]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[target_feature(enable = "name")]`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[target_feature(enable = "name")]`
|
||||||
|
|
||||||
error: attribute should be applied to a function definition
|
error: attribute should be applied to a function definition
|
||||||
--> $DIR/invalid-attribute.rs:34:1
|
--> $DIR/invalid-attribute.rs:17:1
|
||||||
|
|
|
||||||
|
LL | #[target_feature(enable = "sse2")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL |
|
||||||
|
LL | extern crate alloc;
|
||||||
|
| ------------------- not a function definition
|
||||||
|
|
||||||
|
error: attribute should be applied to a function definition
|
||||||
|
--> $DIR/invalid-attribute.rs:22:1
|
||||||
|
|
|
||||||
|
LL | #[target_feature(enable = "sse2")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL |
|
||||||
|
LL | use alloc::alloc::alloc;
|
||||||
|
| ------------------------ not a function definition
|
||||||
|
|
||||||
|
error: attribute should be applied to a function definition
|
||||||
|
--> $DIR/invalid-attribute.rs:27:1
|
||||||
|
|
|
||||||
|
LL | #[target_feature(enable = "sse2")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL |
|
||||||
|
LL | extern "Rust" {}
|
||||||
|
| ---------------- not a function definition
|
||||||
|
|
||||||
|
error: attribute should be applied to a function definition
|
||||||
|
--> $DIR/invalid-attribute.rs:49:1
|
||||||
|
|
|
|
||||||
LL | #[target_feature(enable = "sse2")]
|
LL | #[target_feature(enable = "sse2")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -14,7 +41,7 @@ LL | mod another {}
|
|||||||
| -------------- not a function definition
|
| -------------- not a function definition
|
||||||
|
|
||||||
error: attribute should be applied to a function definition
|
error: attribute should be applied to a function definition
|
||||||
--> $DIR/invalid-attribute.rs:39:1
|
--> $DIR/invalid-attribute.rs:54:1
|
||||||
|
|
|
|
||||||
LL | #[target_feature(enable = "sse2")]
|
LL | #[target_feature(enable = "sse2")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -23,7 +50,7 @@ LL | const FOO: usize = 7;
|
|||||||
| --------------------- not a function definition
|
| --------------------- not a function definition
|
||||||
|
|
||||||
error: attribute should be applied to a function definition
|
error: attribute should be applied to a function definition
|
||||||
--> $DIR/invalid-attribute.rs:44:1
|
--> $DIR/invalid-attribute.rs:59:1
|
||||||
|
|
|
|
||||||
LL | #[target_feature(enable = "sse2")]
|
LL | #[target_feature(enable = "sse2")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -32,7 +59,7 @@ LL | struct Foo;
|
|||||||
| ----------- not a function definition
|
| ----------- not a function definition
|
||||||
|
|
||||||
error: attribute should be applied to a function definition
|
error: attribute should be applied to a function definition
|
||||||
--> $DIR/invalid-attribute.rs:49:1
|
--> $DIR/invalid-attribute.rs:64:1
|
||||||
|
|
|
|
||||||
LL | #[target_feature(enable = "sse2")]
|
LL | #[target_feature(enable = "sse2")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -41,7 +68,7 @@ LL | enum Bar {}
|
|||||||
| ----------- not a function definition
|
| ----------- not a function definition
|
||||||
|
|
||||||
error: attribute should be applied to a function definition
|
error: attribute should be applied to a function definition
|
||||||
--> $DIR/invalid-attribute.rs:54:1
|
--> $DIR/invalid-attribute.rs:69:1
|
||||||
|
|
|
|
||||||
LL | #[target_feature(enable = "sse2")]
|
LL | #[target_feature(enable = "sse2")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -54,7 +81,16 @@ LL | | }
|
|||||||
| |_- not a function definition
|
| |_- not a function definition
|
||||||
|
|
||||||
error: attribute should be applied to a function definition
|
error: attribute should be applied to a function definition
|
||||||
--> $DIR/invalid-attribute.rs:62:1
|
--> $DIR/invalid-attribute.rs:77:1
|
||||||
|
|
|
||||||
|
LL | #[target_feature(enable = "sse2")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL |
|
||||||
|
LL | type Uwu = ();
|
||||||
|
| -------------- not a function definition
|
||||||
|
|
||||||
|
error: attribute should be applied to a function definition
|
||||||
|
--> $DIR/invalid-attribute.rs:82:1
|
||||||
|
|
|
|
||||||
LL | #[target_feature(enable = "sse2")]
|
LL | #[target_feature(enable = "sse2")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -63,7 +99,34 @@ LL | trait Baz {}
|
|||||||
| ------------ not a function definition
|
| ------------ not a function definition
|
||||||
|
|
||||||
error: attribute should be applied to a function definition
|
error: attribute should be applied to a function definition
|
||||||
--> $DIR/invalid-attribute.rs:85:5
|
--> $DIR/invalid-attribute.rs:92:1
|
||||||
|
|
|
||||||
|
LL | #[target_feature(enable = "sse2")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL |
|
||||||
|
LL | static A: () = ();
|
||||||
|
| ------------------ not a function definition
|
||||||
|
|
||||||
|
error: attribute should be applied to a function definition
|
||||||
|
--> $DIR/invalid-attribute.rs:97:1
|
||||||
|
|
|
||||||
|
LL | #[target_feature(enable = "sse2")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL |
|
||||||
|
LL | impl Quux for u8 {}
|
||||||
|
| ------------------- not a function definition
|
||||||
|
|
||||||
|
error: attribute should be applied to a function definition
|
||||||
|
--> $DIR/invalid-attribute.rs:102:1
|
||||||
|
|
|
||||||
|
LL | #[target_feature(enable = "sse2")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
LL |
|
||||||
|
LL | impl Foo {}
|
||||||
|
| ----------- not a function definition
|
||||||
|
|
||||||
|
error: attribute should be applied to a function definition
|
||||||
|
--> $DIR/invalid-attribute.rs:120:5
|
||||||
|
|
|
|
||||||
LL | #[target_feature(enable = "sse2")]
|
LL | #[target_feature(enable = "sse2")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -75,7 +138,7 @@ LL | | }
|
|||||||
| |_____- not a function definition
|
| |_____- not a function definition
|
||||||
|
|
||||||
error: attribute should be applied to a function definition
|
error: attribute should be applied to a function definition
|
||||||
--> $DIR/invalid-attribute.rs:93:5
|
--> $DIR/invalid-attribute.rs:128:5
|
||||||
|
|
|
|
||||||
LL | #[target_feature(enable = "sse2")]
|
LL | #[target_feature(enable = "sse2")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -84,25 +147,25 @@ LL | || {};
|
|||||||
| ----- not a function definition
|
| ----- not a function definition
|
||||||
|
|
||||||
error: the feature named `foo` is not valid for this target
|
error: the feature named `foo` is not valid for this target
|
||||||
--> $DIR/invalid-attribute.rs:19:18
|
--> $DIR/invalid-attribute.rs:34:18
|
||||||
|
|
|
|
||||||
LL | #[target_feature(enable = "foo")]
|
LL | #[target_feature(enable = "foo")]
|
||||||
| ^^^^^^^^^^^^^^ `foo` is not valid for this target
|
| ^^^^^^^^^^^^^^ `foo` is not valid for this target
|
||||||
|
|
||||||
error: malformed `target_feature` attribute input
|
error: malformed `target_feature` attribute input
|
||||||
--> $DIR/invalid-attribute.rs:22:18
|
--> $DIR/invalid-attribute.rs:37:18
|
||||||
|
|
|
|
||||||
LL | #[target_feature(bar)]
|
LL | #[target_feature(bar)]
|
||||||
| ^^^ help: must be of the form: `enable = ".."`
|
| ^^^ help: must be of the form: `enable = ".."`
|
||||||
|
|
||||||
error: malformed `target_feature` attribute input
|
error: malformed `target_feature` attribute input
|
||||||
--> $DIR/invalid-attribute.rs:24:18
|
--> $DIR/invalid-attribute.rs:39:18
|
||||||
|
|
|
|
||||||
LL | #[target_feature(disable = "baz")]
|
LL | #[target_feature(disable = "baz")]
|
||||||
| ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."`
|
| ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."`
|
||||||
|
|
||||||
error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
|
error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
|
||||||
--> $DIR/invalid-attribute.rs:28:1
|
--> $DIR/invalid-attribute.rs:43:1
|
||||||
|
|
|
|
||||||
LL | #[target_feature(enable = "sse2")]
|
LL | #[target_feature(enable = "sse2")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -114,13 +177,13 @@ LL | fn bar() {}
|
|||||||
= help: add `#![feature(target_feature_11)]` to the crate attributes to enable
|
= help: add `#![feature(target_feature_11)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: cannot use `#[inline(always)]` with `#[target_feature]`
|
error: cannot use `#[inline(always)]` with `#[target_feature]`
|
||||||
--> $DIR/invalid-attribute.rs:67:1
|
--> $DIR/invalid-attribute.rs:87:1
|
||||||
|
|
|
|
||||||
LL | #[inline(always)]
|
LL | #[inline(always)]
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
|
error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
|
||||||
--> $DIR/invalid-attribute.rs:77:5
|
--> $DIR/invalid-attribute.rs:112:5
|
||||||
|
|
|
|
||||||
LL | #[target_feature(enable = "sse2")]
|
LL | #[target_feature(enable = "sse2")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -131,6 +194,6 @@ LL | fn foo() {}
|
|||||||
= note: see issue #69098 <https://github.com/rust-lang/rust/issues/69098> for more information
|
= note: see issue #69098 <https://github.com/rust-lang/rust/issues/69098> for more information
|
||||||
= help: add `#![feature(target_feature_11)]` to the crate attributes to enable
|
= help: add `#![feature(target_feature_11)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to 15 previous errors
|
error: aborting due to 22 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
Loading…
Reference in New Issue
Block a user