Skip to content

Commit 4596ce6

Browse files
committed
switch to an allowlist approach
1 parent 4d082b7 commit 4596ce6

File tree

9 files changed

+110
-31
lines changed

9 files changed

+110
-31
lines changed
Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
Functions marked with the `#[naked]` attribute are restricted in what other
2-
code generation attributes they may be marked with.
2+
attributes they may be marked with.
33

4-
The following code generation attributes are incompatible with `#[naked]`:
4+
Notable attributes that are incompatible with `#[naked]` are:
55

6-
* `#[inline]`
7-
* `#[track_caller]`
8-
* `#[target_feature]`
6+
* `#[inline]`
7+
* `#[track_caller]`
8+
* `#[target_feature]`
9+
* `#[test]`, `#[ignore]`, `#[should_panic]`
910

1011
Erroneous code example:
1112

@@ -18,7 +19,3 @@ fn foo() {}
1819
These incompatibilities are due to the fact that naked functions deliberately
1920
impose strict restrictions regarding the code that the compiler is
2021
allowed to produce for this function.
21-
22-
See [the reference page for codegen attributes] for more information.
23-
24-
[the reference page for codegen attributes]: https://doc.rust-lang.org/reference/attributes/codegen.html

compiler/rustc_passes/messages.ftl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -482,8 +482,8 @@ passes_naked_functions_asm_block =
482482
passes_naked_functions_asm_options =
483483
asm options unsupported in naked functions: {$unsupported_options}
484484
485-
passes_naked_functions_codegen_attribute =
486-
cannot use additional code generation attributes with `#[naked]`
485+
passes_naked_functions_incompatible_attribute =
486+
attribute incompatible with `#[naked]`
487487
.label = this attribute is incompatible with `#[naked]`
488488
.naked_attribute = function marked with `#[naked]` here
489489

compiler/rustc_passes/src/check_attr.rs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -418,15 +418,47 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
418418
target: Target,
419419
attrs: &[Attribute],
420420
) -> bool {
421-
const FORBIDDEN: [rustc_span::Symbol; 3] =
422-
[sym::track_caller, sym::inline, sym::target_feature];
421+
// many attributes don't make sense in combination with #[naked].
422+
// Notable attributes that are incompatible with `#[naked]` are:
423+
//
424+
// * `#[inline]`
425+
// * `#[track_caller]`
426+
// * `#[target_feature]`
427+
// * `#[test]`, `#[ignore]`, `#[should_panic]`
428+
//
429+
// NOTE: when making changes to this list, check that `error_codes/E0736.md` remains accurate
430+
const ALLOW_LIST: &[rustc_span::Symbol] = &[
431+
// conditional compilation
432+
sym::cfg,
433+
sym::cfg_attr,
434+
// testing (allowed here so better errors can be generated in `rustc_builtin_macros::test`)
435+
sym::test,
436+
sym::ignore,
437+
sym::should_panic,
438+
// diagnostics
439+
sym::allow,
440+
sym::warn,
441+
sym::deny,
442+
sym::forbid,
443+
sym::deprecated,
444+
sym::must_use,
445+
// abi, linking and FFI
446+
sym::export_name,
447+
sym::link_section,
448+
sym::no_mangle,
449+
sym::naked,
450+
// code generation
451+
sym::cold,
452+
// documentation
453+
sym::doc,
454+
];
423455

424456
match target {
425457
Target::Fn
426458
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {
427459
for other_attr in attrs {
428-
if FORBIDDEN.into_iter().any(|name| other_attr.has_name(name)) {
429-
self.dcx().emit_err(errors::NakedFunctionCodegenAttribute {
460+
if !ALLOW_LIST.iter().any(|name| other_attr.has_name(*name)) {
461+
self.dcx().emit_err(errors::NakedFunctionIncompatibleAttribute {
430462
span: other_attr.span,
431463
naked_span: attr.span,
432464
});

compiler/rustc_passes/src/errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,8 +1183,8 @@ pub struct NakedFunctionsMustUseNoreturn {
11831183
}
11841184

11851185
#[derive(Diagnostic)]
1186-
#[diag(passes_naked_functions_codegen_attribute, code = E0736)]
1187-
pub struct NakedFunctionCodegenAttribute {
1186+
#[diag(passes_naked_functions_incompatible_attribute, code = E0736)]
1187+
pub struct NakedFunctionIncompatibleAttribute {
11881188
#[primary_span]
11891189
#[label]
11901190
pub span: Span,

tests/ui/asm/naked-functions-inline.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
error[E0736]: cannot use additional code generation attributes with `#[naked]`
1+
error[E0736]: attribute incompatible with `#[naked]`
22
--> $DIR/naked-functions-inline.rs:13:1
33
|
44
LL | #[naked]
55
| -------- function marked with `#[naked]` here
66
LL | #[inline]
77
| ^^^^^^^^^ this attribute is incompatible with `#[naked]`
88

9-
error[E0736]: cannot use additional code generation attributes with `#[naked]`
9+
error[E0736]: attribute incompatible with `#[naked]`
1010
--> $DIR/naked-functions-inline.rs:20:1
1111
|
1212
LL | #[naked]
1313
| -------- function marked with `#[naked]` here
1414
LL | #[inline(always)]
1515
| ^^^^^^^^^^^^^^^^^ this attribute is incompatible with `#[naked]`
1616

17-
error[E0736]: cannot use additional code generation attributes with `#[naked]`
17+
error[E0736]: attribute incompatible with `#[naked]`
1818
--> $DIR/naked-functions-inline.rs:27:1
1919
|
2020
LL | #[naked]

tests/ui/asm/naked-functions-target-feature.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0736]: cannot use additional code generation attributes with `#[naked]`
1+
error[E0736]: attribute incompatible with `#[naked]`
22
--> $DIR/naked-functions-target-feature.rs:8:1
33
|
44
LL | #[target_feature(enable = "sse2")]

tests/ui/asm/naked-functions.rs

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,6 @@ pub unsafe extern "C" fn valid_att_syntax() {
162162
asm!("", options(noreturn, att_syntax));
163163
}
164164

165-
#[naked]
166-
pub unsafe extern "C" fn inline_none() {
167-
asm!("", options(noreturn));
168-
}
169-
170165
#[naked]
171166
#[naked]
172167
pub unsafe extern "C" fn allow_compile_error(a: u32) -> u32 {
@@ -186,3 +181,58 @@ pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 {
186181
asm!(invalid_syntax)
187182
//~^ ERROR asm template must be a string literal
188183
}
184+
185+
#[cfg(target_arch = "x86_64")]
186+
#[cfg_attr(target_pointer_width = "64", no_mangle)]
187+
#[naked]
188+
pub unsafe extern "C" fn compatible_cfg_attributes() {
189+
asm!("", options(noreturn, att_syntax));
190+
}
191+
192+
#[allow(dead_code)]
193+
#[warn(dead_code)]
194+
#[deny(dead_code)]
195+
#[forbid(dead_code)]
196+
#[naked]
197+
pub unsafe extern "C" fn compatible_diagnostic_attributes() {
198+
asm!("", options(noreturn, att_syntax));
199+
}
200+
201+
#[deprecated = "test"]
202+
#[naked]
203+
pub unsafe extern "C" fn compatible_deprecated_attributes() {
204+
asm!("", options(noreturn, att_syntax));
205+
}
206+
207+
#[cfg(target_arch = "x86_64")]
208+
#[must_use]
209+
#[naked]
210+
pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
211+
asm!(
212+
"
213+
mov rax, 42
214+
ret
215+
",
216+
options(noreturn)
217+
)
218+
}
219+
220+
#[export_name = "exported_function_name"]
221+
#[link_section = ".custom_section"]
222+
#[no_mangle]
223+
#[naked]
224+
pub unsafe extern "C" fn compatible_ffi_attributes_1() {
225+
asm!("", options(noreturn, att_syntax));
226+
}
227+
228+
#[cold]
229+
#[naked]
230+
pub unsafe extern "C" fn compatible_codegen_attributes() {
231+
asm!("", options(noreturn, att_syntax));
232+
}
233+
234+
#[doc = "foo bar baz"]
235+
#[naked]
236+
pub unsafe extern "C" fn compatible_doc_attributes() {
237+
asm!("", options(noreturn, att_syntax));
238+
}

tests/ui/asm/naked-functions.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@ LL | asm!("", options(readonly, nostack), options(pure));
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^
66

77
error: this is a user specified error
8-
--> $DIR/naked-functions.rs:173:5
8+
--> $DIR/naked-functions.rs:168:5
99
|
1010
LL | compile_error!("this is a user specified error")
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212

1313
error: this is a user specified error
14-
--> $DIR/naked-functions.rs:179:5
14+
--> $DIR/naked-functions.rs:174:5
1515
|
1616
LL | compile_error!("this is a user specified error");
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1818

1919
error: asm template must be a string literal
20-
--> $DIR/naked-functions.rs:186:10
20+
--> $DIR/naked-functions.rs:181:10
2121
|
2222
LL | asm!(invalid_syntax)
2323
| ^^^^^^^^^^^^^^

tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0736]: cannot use additional code generation attributes with `#[naked]`
1+
error[E0736]: attribute incompatible with `#[naked]`
22
--> $DIR/error-with-naked.rs:6:1
33
|
44
LL | #[track_caller]
@@ -7,7 +7,7 @@ LL |
77
LL | #[naked]
88
| -------- function marked with `#[naked]` here
99

10-
error[E0736]: cannot use additional code generation attributes with `#[naked]`
10+
error[E0736]: attribute incompatible with `#[naked]`
1111
--> $DIR/error-with-naked.rs:18:5
1212
|
1313
LL | #[track_caller]

0 commit comments

Comments
 (0)