Skip to content

Commit c6a166b

Browse files
committed
switch to an allowlist approach
- merge error codes - use attribute name that is incompatible in error message - add test for conditional incompatible attribute - add `linkage` to the allowlist
1 parent 4d082b7 commit c6a166b

16 files changed

+185
-65
lines changed

compiler/rustc_builtin_macros/src/errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,7 @@ pub(crate) struct ExpectedItem<'a> {
914914
}
915915

916916
#[derive(Diagnostic)]
917-
#[diag(builtin_macros_naked_functions_testing_attribute, code = E0798)]
917+
#[diag(builtin_macros_naked_functions_testing_attribute, code = E0736)]
918918
pub struct NakedFunctionTestingAttribute {
919919
#[primary_span]
920920
#[label(builtin_macros_naked_attribute)]
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_error_codes/src/error_codes/E0798.md

Lines changed: 0 additions & 14 deletions
This file was deleted.

compiler/rustc_error_codes/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,6 @@ E0794: 0794,
536536
E0795: 0795,
537537
E0796: 0796,
538538
E0797: 0797,
539-
E0798: 0798,
540539
);
541540
)
542541
}

compiler/rustc_passes/messages.ftl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -482,9 +482,9 @@ 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]`
487-
.label = this attribute is incompatible with `#[naked]`
485+
passes_naked_functions_incompatible_attribute =
486+
attribute incompatible with `#[naked]`
487+
.label = the `{$attr}` attribute is incompatible with `#[naked]`
488488
.naked_attribute = function marked with `#[naked]` here
489489
490490
passes_naked_functions_must_use_noreturn =

compiler/rustc_passes/src/check_attr.rs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -418,17 +418,53 @@ 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+
sym::bench,
439+
// diagnostics
440+
sym::allow,
441+
sym::warn,
442+
sym::deny,
443+
sym::forbid,
444+
sym::deprecated,
445+
sym::must_use,
446+
// abi, linking and FFI
447+
sym::export_name,
448+
sym::link_section,
449+
sym::linkage,
450+
sym::no_mangle,
451+
sym::naked,
452+
sym::instruction_set,
453+
// code generation
454+
sym::cold,
455+
// documentation
456+
sym::doc,
457+
];
423458

424459
match target {
425460
Target::Fn
426461
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {
427462
for other_attr in attrs {
428-
if FORBIDDEN.into_iter().any(|name| other_attr.has_name(name)) {
429-
self.dcx().emit_err(errors::NakedFunctionCodegenAttribute {
463+
if !ALLOW_LIST.iter().any(|name| other_attr.has_name(*name)) {
464+
self.dcx().emit_err(errors::NakedFunctionIncompatibleAttribute {
430465
span: other_attr.span,
431466
naked_span: attr.span,
467+
attr: other_attr.name_or_empty(),
432468
});
433469

434470
return false;

compiler/rustc_passes/src/errors.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,13 +1183,14 @@ 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,
11911191
#[label(passes_naked_attribute)]
11921192
pub naked_span: Span,
1193+
pub attr: Symbol,
11931194
}
11941195

11951196
#[derive(Diagnostic)]

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,10 @@ pub unsafe extern "C" fn inline_always() {
2929
pub unsafe extern "C" fn inline_never() {
3030
asm!("", options(noreturn));
3131
}
32+
33+
#[naked]
34+
#[cfg_attr(all(), inline(never))]
35+
//~^ ERROR [E0736]
36+
pub unsafe extern "C" fn conditional_inline_never() {
37+
asm!("", options(noreturn));
38+
}
Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,35 @@
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]
7-
| ^^^^^^^^^ this attribute is incompatible with `#[naked]`
7+
| ^^^^^^^^^ the `inline` 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)]
15-
| ^^^^^^^^^^^^^^^^^ this attribute is incompatible with `#[naked]`
15+
| ^^^^^^^^^^^^^^^^^ the `inline` 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]
2121
| -------- function marked with `#[naked]` here
2222
LL | #[inline(never)]
23-
| ^^^^^^^^^^^^^^^^ this attribute is incompatible with `#[naked]`
23+
| ^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
2424

25-
error: aborting due to 3 previous errors
25+
error[E0736]: attribute incompatible with `#[naked]`
26+
--> $DIR/naked-functions-inline.rs:34:19
27+
|
28+
LL | #[naked]
29+
| -------- function marked with `#[naked]` here
30+
LL | #[cfg_attr(all(), inline(never))]
31+
| ^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
32+
33+
error: aborting due to 4 previous errors
2634

2735
For more information about this error, try `rustc --explain E0736`.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//@ compile-flags: --target armv5te-unknown-linux-gnueabi
2+
//@ needs-llvm-components: arm
3+
//@ needs-asm-support
4+
//@ build-pass
5+
6+
#![crate_type = "lib"]
7+
#![feature(no_core, lang_items, rustc_attrs, naked_functions)]
8+
#![no_core]
9+
10+
#[rustc_builtin_macro]
11+
macro_rules! asm {
12+
() => {};
13+
}
14+
15+
#[lang = "sized"]
16+
trait Sized {}
17+
18+
#[no_mangle]
19+
#[naked]
20+
#[instruction_set(arm::t32)]
21+
unsafe extern "C" fn test_thumb() {
22+
asm!("bx lr", options(noreturn));
23+
}
24+
25+
#[no_mangle]
26+
#[naked]
27+
#[instruction_set(arm::t32)]
28+
unsafe extern "C" fn test_arm() {
29+
asm!("bx lr", options(noreturn));
30+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
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")]
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this attribute is incompatible with `#[naked]`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `target_feature` attribute is incompatible with `#[naked]`
66
LL |
77
LL | #[naked]
88
| -------- function marked with `#[naked]` here

tests/ui/asm/naked-functions-testattrs.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,30 @@ use std::arch::asm;
1010

1111
#[test]
1212
#[naked]
13-
//~^ ERROR [E0798]
13+
//~^ ERROR [E0736]
1414
fn test_naked() {
1515
unsafe { asm!("", options(noreturn)) };
1616
}
1717

1818
#[should_panic]
1919
#[test]
2020
#[naked]
21-
//~^ ERROR [E0798]
21+
//~^ ERROR [E0736]
2222
fn test_naked_should_panic() {
2323
unsafe { asm!("", options(noreturn)) };
2424
}
2525

2626
#[ignore]
2727
#[test]
2828
#[naked]
29-
//~^ ERROR [E0798]
29+
//~^ ERROR [E0736]
3030
fn test_naked_ignore() {
3131
unsafe { asm!("", options(noreturn)) };
3232
}
3333

3434
#[bench]
3535
#[naked]
36-
//~^ ERROR [E0798]
36+
//~^ ERROR [E0736]
3737
fn bench_naked() {
3838
unsafe { asm!("", options(noreturn)) };
3939
}
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1-
error[E0798]: cannot use `#[naked]` with testing attributes
1+
error[E0736]: cannot use `#[naked]` with testing attributes
22
--> $DIR/naked-functions-testattrs.rs:12:1
33
|
44
LL | #[test]
55
| ------- function marked with testing attribute here
66
LL | #[naked]
77
| ^^^^^^^^ `#[naked]` is incompatible with testing attributes
88

9-
error[E0798]: cannot use `#[naked]` with testing attributes
9+
error[E0736]: cannot use `#[naked]` with testing attributes
1010
--> $DIR/naked-functions-testattrs.rs:20:1
1111
|
1212
LL | #[test]
1313
| ------- function marked with testing attribute here
1414
LL | #[naked]
1515
| ^^^^^^^^ `#[naked]` is incompatible with testing attributes
1616

17-
error[E0798]: cannot use `#[naked]` with testing attributes
17+
error[E0736]: cannot use `#[naked]` with testing attributes
1818
--> $DIR/naked-functions-testattrs.rs:28:1
1919
|
2020
LL | #[test]
2121
| ------- function marked with testing attribute here
2222
LL | #[naked]
2323
| ^^^^^^^^ `#[naked]` is incompatible with testing attributes
2424

25-
error[E0798]: cannot use `#[naked]` with testing attributes
25+
error[E0736]: cannot use `#[naked]` with testing attributes
2626
--> $DIR/naked-functions-testattrs.rs:35:1
2727
|
2828
LL | #[bench]
@@ -32,4 +32,4 @@ LL | #[naked]
3232

3333
error: aborting due to 4 previous errors
3434

35-
For more information about this error, try `rustc --explain E0798`.
35+
For more information about this error, try `rustc --explain E0736`.

0 commit comments

Comments
 (0)