Skip to content

Commit 773ddba

Browse files
committed
Auto merge of #79388 - tmiasko:naked-def-only, r=lcnr
Validate that `#[naked]` is applied to a function definition
2 parents ec039bd + 75e00e8 commit 773ddba

File tree

5 files changed

+116
-14
lines changed

5 files changed

+116
-14
lines changed

compiler/rustc_passes/src/check_attr.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ impl CheckAttrVisitor<'tcx> {
8989
self.check_allow_internal_unstable(&attr, span, target, &attrs)
9090
} else if self.tcx.sess.check_name(attr, sym::rustc_allow_const_fn_unstable) {
9191
self.check_rustc_allow_const_fn_unstable(hir_id, &attr, span, target)
92+
} else if self.tcx.sess.check_name(attr, sym::naked) {
93+
self.check_naked(attr, span, target)
9294
} else {
9395
// lint-only checks
9496
if self.tcx.sess.check_name(attr, sym::cold) {
@@ -162,6 +164,25 @@ impl CheckAttrVisitor<'tcx> {
162164
}
163165
}
164166

167+
/// Checks if `#[naked]` is applied to a function definition.
168+
fn check_naked(&self, attr: &Attribute, span: &Span, target: Target) -> bool {
169+
match target {
170+
Target::Fn
171+
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
172+
_ => {
173+
self.tcx
174+
.sess
175+
.struct_span_err(
176+
attr.span,
177+
"attribute should be applied to a function definition",
178+
)
179+
.span_label(*span, "not a function definition")
180+
.emit();
181+
false
182+
}
183+
}
184+
}
185+
165186
/// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid.
166187
fn check_track_caller(
167188
&self,
@@ -171,7 +192,7 @@ impl CheckAttrVisitor<'tcx> {
171192
target: Target,
172193
) -> bool {
173194
match target {
174-
_ if self.tcx.sess.contains_name(attrs, sym::naked) => {
195+
_ if attrs.iter().any(|attr| attr.has_name(sym::naked)) => {
175196
struct_span_err!(
176197
self.tcx.sess,
177198
*attr_span,

src/test/ui/asm/naked-invalid-attr.rs

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Checks that #[naked] attribute can be placed on function definitions only.
2+
//
3+
// ignore-wasm32 asm unsupported
4+
#![feature(asm)]
5+
#![feature(naked_functions)]
6+
#![naked] //~ ERROR should be applied to a function definition
7+
8+
extern "C" {
9+
#[naked] //~ ERROR should be applied to a function definition
10+
fn f();
11+
}
12+
13+
#[naked] //~ ERROR should be applied to a function definition
14+
#[repr(C)]
15+
struct S {
16+
a: u32,
17+
b: u32,
18+
}
19+
20+
trait Invoke {
21+
#[naked] //~ ERROR should be applied to a function definition
22+
extern "C" fn invoke(&self);
23+
}
24+
25+
impl Invoke for S {
26+
#[naked]
27+
extern "C" fn invoke(&self) {
28+
unsafe { asm!("", options(noreturn)) }
29+
}
30+
}
31+
32+
#[naked]
33+
extern "C" fn ok() {
34+
unsafe { asm!("", options(noreturn)) }
35+
}
36+
37+
impl S {
38+
#[naked]
39+
extern "C" fn g() {
40+
unsafe { asm!("", options(noreturn)) }
41+
}
42+
43+
#[naked]
44+
extern "C" fn h(&self) {
45+
unsafe { asm!("", options(noreturn)) }
46+
}
47+
}
48+
49+
fn main() {
50+
#[naked] || {}; //~ ERROR should be applied to a function definition
51+
}
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
error: attribute should be applied to a function definition
2+
--> $DIR/naked-invalid-attr.rs:9:5
3+
|
4+
LL | #[naked]
5+
| ^^^^^^^^
6+
LL | fn f();
7+
| ------- not a function definition
8+
9+
error: attribute should be applied to a function definition
10+
--> $DIR/naked-invalid-attr.rs:13:1
11+
|
12+
LL | #[naked]
13+
| ^^^^^^^^
14+
LL | #[repr(C)]
15+
LL | / struct S {
16+
LL | | a: u32,
17+
LL | | b: u32,
18+
LL | | }
19+
| |_- not a function definition
20+
21+
error: attribute should be applied to a function definition
22+
--> $DIR/naked-invalid-attr.rs:50:5
23+
|
24+
LL | #[naked] || {};
25+
| ^^^^^^^^ ----- not a function definition
26+
27+
error: attribute should be applied to a function definition
28+
--> $DIR/naked-invalid-attr.rs:21:5
29+
|
30+
LL | #[naked]
31+
| ^^^^^^^^
32+
LL | extern "C" fn invoke(&self);
33+
| ---------------------------- not a function definition
34+
35+
error: attribute should be applied to a function definition
36+
--> $DIR/naked-invalid-attr.rs:6:1
37+
|
38+
LL | #![naked]
39+
| ^^^^^^^^^
40+
41+
error: aborting due to 5 previous errors
42+

src/test/ui/rfc-2091-track-caller/error-with-naked.rs

-6
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,4 @@ impl S {
1212
fn g() {}
1313
}
1414

15-
extern "Rust" {
16-
#[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]`
17-
#[naked]
18-
fn h();
19-
}
20-
2115
fn main() {}

src/test/ui/rfc-2091-track-caller/error-with-naked.stderr

+1-7
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,12 @@ error[E0736]: cannot use `#[track_caller]` with `#[naked]`
44
LL | #[track_caller]
55
| ^^^^^^^^^^^^^^^
66

7-
error[E0736]: cannot use `#[track_caller]` with `#[naked]`
8-
--> $DIR/error-with-naked.rs:16:5
9-
|
10-
LL | #[track_caller]
11-
| ^^^^^^^^^^^^^^^
12-
137
error[E0736]: cannot use `#[track_caller]` with `#[naked]`
148
--> $DIR/error-with-naked.rs:10:5
159
|
1610
LL | #[track_caller]
1711
| ^^^^^^^^^^^^^^^
1812

19-
error: aborting due to 3 previous errors
13+
error: aborting due to 2 previous errors
2014

2115
For more information about this error, try `rustc --explain E0736`.

0 commit comments

Comments
 (0)