Skip to content

Commit 30cd4b3

Browse files
authored
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
2 parents f6f238f + 34be05e commit 30cd4b3

File tree

3 files changed

+139
-36
lines changed

3 files changed

+139
-36
lines changed

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

+25-20
Original file line numberDiff line numberDiff line change
@@ -61,25 +61,29 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
6161

6262
let supported_target_features = tcx.supported_target_features(LOCAL_CRATE);
6363

64-
// In some cases, attribute are only valid on functions, but it's the `check_attr`
65-
// pass that check that they aren't used anywhere else, rather this module.
66-
// In these cases, we bail from performing further checks that are only meaningful for
67-
// functions (such as calling `fn_sig`, which ICEs if given a non-function). We also
68-
// report a delayed bug, just in case `check_attr` isn't doing its job.
69-
let validate_fn_only_attr = |attr_sp| -> bool {
70-
let def_kind = tcx.def_kind(did);
71-
if let DefKind::Fn | DefKind::AssocFn | DefKind::Variant | DefKind::Ctor(..) = def_kind {
72-
true
73-
} else {
74-
tcx.sess.delay_span_bug(attr_sp, "this attribute can only be applied to functions");
75-
false
76-
}
77-
};
78-
7964
let mut inline_span = None;
8065
let mut link_ordinal_span = None;
8166
let mut no_sanitize_span = None;
67+
8268
for attr in attrs.iter() {
69+
// In some cases, attribute are only valid on functions, but it's the `check_attr`
70+
// pass that check that they aren't used anywhere else, rather this module.
71+
// In these cases, we bail from performing further checks that are only meaningful for
72+
// functions (such as calling `fn_sig`, which ICEs if given a non-function). We also
73+
// report a delayed bug, just in case `check_attr` isn't doing its job.
74+
let fn_sig = || {
75+
use DefKind::*;
76+
77+
let def_kind = tcx.def_kind(did);
78+
if let Fn | AssocFn | Variant | Ctor(..) = def_kind {
79+
Some(tcx.fn_sig(did))
80+
} else {
81+
tcx.sess
82+
.delay_span_bug(attr.span, "this attribute can only be applied to functions");
83+
None
84+
}
85+
};
86+
8387
if attr.has_name(sym::cold) {
8488
codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD;
8589
} else if attr.has_name(sym::rustc_allocator) {
@@ -169,8 +173,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
169173
}
170174
}
171175
} else if attr.has_name(sym::cmse_nonsecure_entry) {
172-
if validate_fn_only_attr(attr.span)
173-
&& !matches!(tcx.fn_sig(did).skip_binder().abi(), abi::Abi::C { .. })
176+
if let Some(fn_sig) = fn_sig()
177+
&& !matches!(fn_sig.skip_binder().abi(), abi::Abi::C { .. })
174178
{
175179
struct_span_err!(
176180
tcx.sess,
@@ -189,8 +193,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
189193
codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
190194
} else if attr.has_name(sym::track_caller) {
191195
if !tcx.is_closure(did.to_def_id())
192-
&& validate_fn_only_attr(attr.span)
193-
&& tcx.fn_sig(did).skip_binder().abi() != abi::Abi::Rust
196+
&& let Some(fn_sig) = fn_sig()
197+
&& fn_sig.skip_binder().abi() != abi::Abi::Rust
194198
{
195199
struct_span_err!(tcx.sess, attr.span, E0737, "`#[track_caller]` requires Rust ABI")
196200
.emit();
@@ -222,7 +226,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
222226
}
223227
} else if attr.has_name(sym::target_feature) {
224228
if !tcx.is_closure(did.to_def_id())
225-
&& tcx.fn_sig(did).skip_binder().unsafety() == hir::Unsafety::Normal
229+
&& let Some(fn_sig) = fn_sig()
230+
&& fn_sig.skip_binder().unsafety() == hir::Unsafety::Normal
226231
{
227232
if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc {
228233
// The `#[target_feature]` attribute is allowed on

tests/ui/target-feature/invalid-attribute.rs

+35
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,21 @@
1414

1515
#![warn(unused_attributes)]
1616

17+
#[target_feature(enable = "sse2")]
18+
//~^ ERROR attribute should be applied to a function
19+
extern crate alloc;
20+
//~^ NOTE not a function
21+
22+
#[target_feature(enable = "sse2")]
23+
//~^ ERROR attribute should be applied to a function
24+
use alloc::alloc::alloc;
25+
//~^ NOTE not a function
26+
27+
#[target_feature(enable = "sse2")]
28+
//~^ ERROR attribute should be applied to a function
29+
extern "Rust" {}
30+
//~^ NOTE not a function
31+
1732
#[target_feature = "+sse2"]
1833
//~^ ERROR malformed `target_feature` attribute
1934
#[target_feature(enable = "foo")]
@@ -59,6 +74,11 @@ union Qux {
5974
f2: u16,
6075
}
6176

77+
#[target_feature(enable = "sse2")]
78+
//~^ ERROR attribute should be applied to a function
79+
type Uwu = ();
80+
//~^ NOTE not a function
81+
6282
#[target_feature(enable = "sse2")]
6383
//~^ ERROR attribute should be applied to a function
6484
trait Baz {}
@@ -69,6 +89,21 @@ trait Baz {}
6989
#[target_feature(enable = "sse2")]
7090
unsafe fn test() {}
7191

92+
#[target_feature(enable = "sse2")]
93+
//~^ ERROR attribute should be applied to a function
94+
static A: () = ();
95+
//~^ NOTE not a function
96+
97+
#[target_feature(enable = "sse2")]
98+
//~^ ERROR attribute should be applied to a function
99+
impl Quux for u8 {}
100+
//~^ NOTE not a function
101+
102+
#[target_feature(enable = "sse2")]
103+
//~^ ERROR attribute should be applied to a function
104+
impl Foo {}
105+
//~^ NOTE not a function
106+
72107
trait Quux {
73108
fn foo();
74109
}

tests/ui/target-feature/invalid-attribute.stderr

+79-16
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,38 @@
11
error: malformed `target_feature` attribute input
2-
--> $DIR/invalid-attribute.rs:17:1
2+
--> $DIR/invalid-attribute.rs:32:1
33
|
44
LL | #[target_feature = "+sse2"]
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[target_feature(enable = "name")]`
66

77
error: attribute should be applied to a function definition
8-
--> $DIR/invalid-attribute.rs:34:1
8+
--> $DIR/invalid-attribute.rs:17:1
9+
|
10+
LL | #[target_feature(enable = "sse2")]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
LL |
13+
LL | extern crate alloc;
14+
| ------------------- not a function definition
15+
16+
error: attribute should be applied to a function definition
17+
--> $DIR/invalid-attribute.rs:22:1
18+
|
19+
LL | #[target_feature(enable = "sse2")]
20+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
21+
LL |
22+
LL | use alloc::alloc::alloc;
23+
| ------------------------ not a function definition
24+
25+
error: attribute should be applied to a function definition
26+
--> $DIR/invalid-attribute.rs:27:1
27+
|
28+
LL | #[target_feature(enable = "sse2")]
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
30+
LL |
31+
LL | extern "Rust" {}
32+
| ---------------- not a function definition
33+
34+
error: attribute should be applied to a function definition
35+
--> $DIR/invalid-attribute.rs:49:1
936
|
1037
LL | #[target_feature(enable = "sse2")]
1138
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -14,7 +41,7 @@ LL | mod another {}
1441
| -------------- not a function definition
1542

1643
error: attribute should be applied to a function definition
17-
--> $DIR/invalid-attribute.rs:39:1
44+
--> $DIR/invalid-attribute.rs:54:1
1845
|
1946
LL | #[target_feature(enable = "sse2")]
2047
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -23,7 +50,7 @@ LL | const FOO: usize = 7;
2350
| --------------------- not a function definition
2451

2552
error: attribute should be applied to a function definition
26-
--> $DIR/invalid-attribute.rs:44:1
53+
--> $DIR/invalid-attribute.rs:59:1
2754
|
2855
LL | #[target_feature(enable = "sse2")]
2956
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +59,7 @@ LL | struct Foo;
3259
| ----------- not a function definition
3360

3461
error: attribute should be applied to a function definition
35-
--> $DIR/invalid-attribute.rs:49:1
62+
--> $DIR/invalid-attribute.rs:64:1
3663
|
3764
LL | #[target_feature(enable = "sse2")]
3865
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -41,7 +68,7 @@ LL | enum Bar {}
4168
| ----------- not a function definition
4269

4370
error: attribute should be applied to a function definition
44-
--> $DIR/invalid-attribute.rs:54:1
71+
--> $DIR/invalid-attribute.rs:69:1
4572
|
4673
LL | #[target_feature(enable = "sse2")]
4774
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -54,7 +81,16 @@ LL | | }
5481
| |_- not a function definition
5582

5683
error: attribute should be applied to a function definition
57-
--> $DIR/invalid-attribute.rs:62:1
84+
--> $DIR/invalid-attribute.rs:77:1
85+
|
86+
LL | #[target_feature(enable = "sse2")]
87+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
88+
LL |
89+
LL | type Uwu = ();
90+
| -------------- not a function definition
91+
92+
error: attribute should be applied to a function definition
93+
--> $DIR/invalid-attribute.rs:82:1
5894
|
5995
LL | #[target_feature(enable = "sse2")]
6096
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -63,7 +99,34 @@ LL | trait Baz {}
6399
| ------------ not a function definition
64100

65101
error: attribute should be applied to a function definition
66-
--> $DIR/invalid-attribute.rs:85:5
102+
--> $DIR/invalid-attribute.rs:92:1
103+
|
104+
LL | #[target_feature(enable = "sse2")]
105+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
106+
LL |
107+
LL | static A: () = ();
108+
| ------------------ not a function definition
109+
110+
error: attribute should be applied to a function definition
111+
--> $DIR/invalid-attribute.rs:97:1
112+
|
113+
LL | #[target_feature(enable = "sse2")]
114+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
115+
LL |
116+
LL | impl Quux for u8 {}
117+
| ------------------- not a function definition
118+
119+
error: attribute should be applied to a function definition
120+
--> $DIR/invalid-attribute.rs:102:1
121+
|
122+
LL | #[target_feature(enable = "sse2")]
123+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
124+
LL |
125+
LL | impl Foo {}
126+
| ----------- not a function definition
127+
128+
error: attribute should be applied to a function definition
129+
--> $DIR/invalid-attribute.rs:120:5
67130
|
68131
LL | #[target_feature(enable = "sse2")]
69132
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -75,7 +138,7 @@ LL | | }
75138
| |_____- not a function definition
76139

77140
error: attribute should be applied to a function definition
78-
--> $DIR/invalid-attribute.rs:93:5
141+
--> $DIR/invalid-attribute.rs:128:5
79142
|
80143
LL | #[target_feature(enable = "sse2")]
81144
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -84,25 +147,25 @@ LL | || {};
84147
| ----- not a function definition
85148

86149
error: the feature named `foo` is not valid for this target
87-
--> $DIR/invalid-attribute.rs:19:18
150+
--> $DIR/invalid-attribute.rs:34:18
88151
|
89152
LL | #[target_feature(enable = "foo")]
90153
| ^^^^^^^^^^^^^^ `foo` is not valid for this target
91154

92155
error: malformed `target_feature` attribute input
93-
--> $DIR/invalid-attribute.rs:22:18
156+
--> $DIR/invalid-attribute.rs:37:18
94157
|
95158
LL | #[target_feature(bar)]
96159
| ^^^ help: must be of the form: `enable = ".."`
97160

98161
error: malformed `target_feature` attribute input
99-
--> $DIR/invalid-attribute.rs:24:18
162+
--> $DIR/invalid-attribute.rs:39:18
100163
|
101164
LL | #[target_feature(disable = "baz")]
102165
| ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."`
103166

104167
error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
105-
--> $DIR/invalid-attribute.rs:28:1
168+
--> $DIR/invalid-attribute.rs:43:1
106169
|
107170
LL | #[target_feature(enable = "sse2")]
108171
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -114,13 +177,13 @@ LL | fn bar() {}
114177
= help: add `#![feature(target_feature_11)]` to the crate attributes to enable
115178

116179
error: cannot use `#[inline(always)]` with `#[target_feature]`
117-
--> $DIR/invalid-attribute.rs:67:1
180+
--> $DIR/invalid-attribute.rs:87:1
118181
|
119182
LL | #[inline(always)]
120183
| ^^^^^^^^^^^^^^^^^
121184

122185
error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
123-
--> $DIR/invalid-attribute.rs:77:5
186+
--> $DIR/invalid-attribute.rs:112:5
124187
|
125188
LL | #[target_feature(enable = "sse2")]
126189
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -131,6 +194,6 @@ LL | fn foo() {}
131194
= note: see issue #69098 <https://github.com/rust-lang/rust/issues/69098> for more information
132195
= help: add `#![feature(target_feature_11)]` to the crate attributes to enable
133196

134-
error: aborting due to 15 previous errors
197+
error: aborting due to 22 previous errors
135198

136199
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)