Rollup merge of #127853 - folkertdev:naked-function-error-messages, r=bjorn3
`#[naked]`: report incompatible attributes tracking issue: https://github.com/rust-lang/rust/issues/90957 this is a re-implementation of https://github.com/rust-lang/rust/pull/93809 by ``@bstrie`` which was closed 2 years ago due to inactivity. This PR takes some of the final comments into account, specifically providing a little more context in error messages, and using an allow list to determine which attributes are compatible with `#[naked]`. Notable attributes that are incompatible with `#[naked]` are: * `#[inline]` * `#[track_caller]` * ~~`#[target_feature]`~~ (this is now allowed, see PR discussion) * `#[test]`, `#[ignore]`, `#[should_panic]` These attributes just directly conflict with what `#[naked]` should do. Naked functions are still important for systems programming, embedded, and operating systems, so I'd like to move them forward.
This commit is contained in:
commit
a13f40dae6
@ -220,6 +220,11 @@ builtin_macros_multiple_defaults = multiple declared defaults
|
||||
.note = only one variant can be default
|
||||
.suggestion = make `{$ident}` default
|
||||
|
||||
builtin_macros_naked_functions_testing_attribute =
|
||||
cannot use `#[naked]` with testing attributes
|
||||
.label = function marked with testing attribute here
|
||||
.naked_attribute = `#[naked]` is incompatible with testing attributes
|
||||
|
||||
builtin_macros_no_default_variant = no default declared
|
||||
.help = make a unit variant default by placing `#[default]` above it
|
||||
.suggestion = make `{$ident}` default
|
||||
|
@ -923,3 +923,13 @@ pub(crate) struct ExpectedItem<'a> {
|
||||
pub span: Span,
|
||||
pub token: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_naked_functions_testing_attribute, code = E0736)]
|
||||
pub struct NakedFunctionTestingAttribute {
|
||||
#[primary_span]
|
||||
#[label(builtin_macros_naked_attribute)]
|
||||
pub naked_span: Span,
|
||||
#[label]
|
||||
pub testing_span: Span,
|
||||
}
|
||||
|
@ -133,6 +133,14 @@ pub(crate) fn expand_test_or_bench(
|
||||
};
|
||||
};
|
||||
|
||||
if let Some(attr) = attr::find_by_name(&item.attrs, sym::naked) {
|
||||
cx.dcx().emit_err(errors::NakedFunctionTestingAttribute {
|
||||
testing_span: attr_sp,
|
||||
naked_span: attr.span,
|
||||
});
|
||||
return vec![Annotatable::Item(item)];
|
||||
}
|
||||
|
||||
// check_*_signature will report any errors in the type so compilation
|
||||
// will fail. We shouldn't try to expand in this case because the errors
|
||||
// would be spurious.
|
||||
|
@ -1,14 +1,20 @@
|
||||
`#[track_caller]` and `#[naked]` cannot both be applied to the same function.
|
||||
Functions marked with the `#[naked]` attribute are restricted in what other
|
||||
attributes they may be marked with.
|
||||
|
||||
Notable attributes that are incompatible with `#[naked]` are:
|
||||
|
||||
* `#[inline]`
|
||||
* `#[track_caller]`
|
||||
* `#[test]`, `#[ignore]`, `#[should_panic]`
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0736
|
||||
#[inline]
|
||||
#[naked]
|
||||
#[track_caller]
|
||||
fn foo() {}
|
||||
```
|
||||
|
||||
This is primarily due to ABI incompatibilities between the two attributes.
|
||||
See [RFC 2091] for details on this and other limitations.
|
||||
|
||||
[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
|
||||
These incompatibilities are due to the fact that naked functions deliberately
|
||||
impose strict restrictions regarding the code that the compiler is
|
||||
allowed to produce for this function.
|
||||
|
@ -1,4 +1,4 @@
|
||||
`#[track_caller]` can not be applied on struct.
|
||||
`#[track_caller]` must be applied to a function
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
|
@ -69,9 +69,6 @@ passes_break_non_loop =
|
||||
.suggestion = use `break` on its own without a value inside this `{$kind}` loop
|
||||
.break_expr_suggestion = alternatively, you might have meant to use the available loop label
|
||||
|
||||
passes_cannot_inline_naked_function =
|
||||
naked functions cannot be inlined
|
||||
|
||||
passes_cannot_stabilize_deprecated =
|
||||
an API can't be stabilized after it is deprecated
|
||||
.label = invalid version
|
||||
@ -485,6 +482,11 @@ passes_naked_functions_asm_block =
|
||||
passes_naked_functions_asm_options =
|
||||
asm options unsupported in naked functions: {$unsupported_options}
|
||||
|
||||
passes_naked_functions_incompatible_attribute =
|
||||
attribute incompatible with `#[naked]`
|
||||
.label = the `{$attr}` attribute is incompatible with `#[naked]`
|
||||
.naked_attribute = function marked with `#[naked]` here
|
||||
|
||||
passes_naked_functions_must_use_noreturn =
|
||||
asm in naked functions must use `noreturn` option
|
||||
.suggestion = consider specifying that the asm block is responsible for returning from the function
|
||||
@ -492,9 +494,6 @@ passes_naked_functions_must_use_noreturn =
|
||||
passes_naked_functions_operands =
|
||||
only `const` and `sym` operands are supported in naked functions
|
||||
|
||||
passes_naked_tracked_caller =
|
||||
cannot use `#[track_caller]` with `#[naked]`
|
||||
|
||||
passes_no_link =
|
||||
attribute should be applied to an `extern crate` item
|
||||
.label = not an `extern crate` item
|
||||
|
@ -155,7 +155,7 @@ fn check_attributes(
|
||||
[sym::rustc_std_internal_symbol] => {
|
||||
self.check_rustc_std_internal_symbol(attr, span, target)
|
||||
}
|
||||
[sym::naked] => self.check_naked(hir_id, attr, span, target),
|
||||
[sym::naked] => self.check_naked(hir_id, attr, span, target, attrs),
|
||||
[sym::rustc_never_returns_null_ptr] => {
|
||||
self.check_applied_to_fn_or_method(hir_id, attr, span, target)
|
||||
}
|
||||
@ -410,12 +410,71 @@ fn check_generic_attr(
|
||||
}
|
||||
|
||||
/// Checks if `#[naked]` is applied to a function definition.
|
||||
fn check_naked(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool {
|
||||
fn check_naked(
|
||||
&self,
|
||||
hir_id: HirId,
|
||||
attr: &Attribute,
|
||||
span: Span,
|
||||
target: Target,
|
||||
attrs: &[Attribute],
|
||||
) -> bool {
|
||||
// many attributes don't make sense in combination with #[naked].
|
||||
// Notable attributes that are incompatible with `#[naked]` are:
|
||||
//
|
||||
// * `#[inline]`
|
||||
// * `#[track_caller]`
|
||||
// * `#[test]`, `#[ignore]`, `#[should_panic]`
|
||||
//
|
||||
// NOTE: when making changes to this list, check that `error_codes/E0736.md` remains accurate
|
||||
const ALLOW_LIST: &[rustc_span::Symbol] = &[
|
||||
// conditional compilation
|
||||
sym::cfg,
|
||||
sym::cfg_attr,
|
||||
// testing (allowed here so better errors can be generated in `rustc_builtin_macros::test`)
|
||||
sym::test,
|
||||
sym::ignore,
|
||||
sym::should_panic,
|
||||
sym::bench,
|
||||
// diagnostics
|
||||
sym::allow,
|
||||
sym::warn,
|
||||
sym::deny,
|
||||
sym::forbid,
|
||||
sym::deprecated,
|
||||
sym::must_use,
|
||||
// abi, linking and FFI
|
||||
sym::export_name,
|
||||
sym::link_section,
|
||||
sym::linkage,
|
||||
sym::no_mangle,
|
||||
sym::naked,
|
||||
sym::instruction_set,
|
||||
// code generation
|
||||
sym::cold,
|
||||
sym::target_feature,
|
||||
// documentation
|
||||
sym::doc,
|
||||
];
|
||||
|
||||
match target {
|
||||
Target::Fn
|
||||
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
|
||||
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {
|
||||
for other_attr in attrs {
|
||||
if !ALLOW_LIST.iter().any(|name| other_attr.has_name(*name)) {
|
||||
self.dcx().emit_err(errors::NakedFunctionIncompatibleAttribute {
|
||||
span: other_attr.span,
|
||||
naked_span: attr.span,
|
||||
attr: other_attr.name_or_empty(),
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an
|
||||
// `#[allow_internal_unstable]` attribute with just a lint, because we previously
|
||||
// `#[naked]` attribute with just a lint, because we previously
|
||||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
@ -488,7 +547,7 @@ fn check_collapse_debuginfo(&self, attr: &Attribute, span: Span, target: Target)
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid.
|
||||
/// Checks if a `#[track_caller]` is applied to a function. Returns `true` if valid.
|
||||
fn check_track_caller(
|
||||
&self,
|
||||
hir_id: HirId,
|
||||
@ -498,10 +557,6 @@ fn check_track_caller(
|
||||
target: Target,
|
||||
) -> bool {
|
||||
match target {
|
||||
_ if attrs.iter().any(|attr| attr.has_name(sym::naked)) => {
|
||||
self.dcx().emit_err(errors::NakedTrackedCaller { attr_span });
|
||||
false
|
||||
}
|
||||
Target::Fn => {
|
||||
// `#[track_caller]` is not valid on weak lang items because they are called via
|
||||
// `extern` declarations and `#[track_caller]` would alter their ABI.
|
||||
|
@ -79,13 +79,6 @@ pub struct AttrShouldBeAppliedToFn {
|
||||
pub on_crate: bool,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_naked_tracked_caller, code = E0736)]
|
||||
pub struct NakedTrackedCaller {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_should_be_applied_to_fn, code = E0739)]
|
||||
pub struct TrackedCallerWrongLocation {
|
||||
@ -1124,13 +1117,6 @@ pub struct UnlabeledCfInWhileCondition<'a> {
|
||||
pub cf_type: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_cannot_inline_naked_function)]
|
||||
pub struct CannotInlineNakedFunction {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(passes_undefined_naked_function_abi)]
|
||||
pub struct UndefinedNakedFunctionAbi;
|
||||
@ -1196,6 +1182,17 @@ pub struct NakedFunctionsMustUseNoreturn {
|
||||
pub last_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_naked_functions_incompatible_attribute, code = E0736)]
|
||||
pub struct NakedFunctionIncompatibleAttribute {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[label(passes_naked_attribute)]
|
||||
pub naked_span: Span,
|
||||
pub attr: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_attr_only_in_functions)]
|
||||
pub struct AttrOnlyInFunctions {
|
||||
|
@ -14,9 +14,8 @@
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use crate::errors::{
|
||||
CannotInlineNakedFunction, NakedFunctionsAsmBlock, NakedFunctionsAsmOptions,
|
||||
NakedFunctionsMustUseNoreturn, NakedFunctionsOperands, NoPatterns, ParamsNotAllowed,
|
||||
UndefinedNakedFunctionAbi,
|
||||
NakedFunctionsAsmBlock, NakedFunctionsAsmOptions, NakedFunctionsMustUseNoreturn,
|
||||
NakedFunctionsOperands, NoPatterns, ParamsNotAllowed, UndefinedNakedFunctionAbi,
|
||||
};
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
@ -53,15 +52,6 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
|
||||
check_no_patterns(tcx, body.params);
|
||||
check_no_parameters_use(tcx, body);
|
||||
check_asm(tcx, def_id, body);
|
||||
check_inline(tcx, def_id);
|
||||
}
|
||||
}
|
||||
|
||||
/// Check that the function isn't inlined.
|
||||
fn check_inline(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
let attrs = tcx.get_attrs(def_id, sym::inline);
|
||||
for attr in attrs {
|
||||
tcx.dcx().emit_err(CannotInlineNakedFunction { span: attr.span });
|
||||
}
|
||||
}
|
||||
|
||||
|
38
tests/ui/asm/naked-functions-inline.rs
Normal file
38
tests/ui/asm/naked-functions-inline.rs
Normal file
@ -0,0 +1,38 @@
|
||||
//@ needs-asm-support
|
||||
#![feature(naked_functions)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
use std::arch::asm;
|
||||
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn inline_none() {
|
||||
asm!("", options(noreturn));
|
||||
}
|
||||
|
||||
#[naked]
|
||||
#[inline]
|
||||
//~^ ERROR [E0736]
|
||||
pub unsafe extern "C" fn inline_hint() {
|
||||
asm!("", options(noreturn));
|
||||
}
|
||||
|
||||
#[naked]
|
||||
#[inline(always)]
|
||||
//~^ ERROR [E0736]
|
||||
pub unsafe extern "C" fn inline_always() {
|
||||
asm!("", options(noreturn));
|
||||
}
|
||||
|
||||
#[naked]
|
||||
#[inline(never)]
|
||||
//~^ ERROR [E0736]
|
||||
pub unsafe extern "C" fn inline_never() {
|
||||
asm!("", options(noreturn));
|
||||
}
|
||||
|
||||
#[naked]
|
||||
#[cfg_attr(all(), inline(never))]
|
||||
//~^ ERROR [E0736]
|
||||
pub unsafe extern "C" fn conditional_inline_never() {
|
||||
asm!("", options(noreturn));
|
||||
}
|
35
tests/ui/asm/naked-functions-inline.stderr
Normal file
35
tests/ui/asm/naked-functions-inline.stderr
Normal file
@ -0,0 +1,35 @@
|
||||
error[E0736]: attribute incompatible with `#[naked]`
|
||||
--> $DIR/naked-functions-inline.rs:13:1
|
||||
|
|
||||
LL | #[naked]
|
||||
| -------- function marked with `#[naked]` here
|
||||
LL | #[inline]
|
||||
| ^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
|
||||
|
||||
error[E0736]: attribute incompatible with `#[naked]`
|
||||
--> $DIR/naked-functions-inline.rs:20:1
|
||||
|
|
||||
LL | #[naked]
|
||||
| -------- function marked with `#[naked]` here
|
||||
LL | #[inline(always)]
|
||||
| ^^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
|
||||
|
||||
error[E0736]: attribute incompatible with `#[naked]`
|
||||
--> $DIR/naked-functions-inline.rs:27:1
|
||||
|
|
||||
LL | #[naked]
|
||||
| -------- function marked with `#[naked]` here
|
||||
LL | #[inline(never)]
|
||||
| ^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
|
||||
|
||||
error[E0736]: attribute incompatible with `#[naked]`
|
||||
--> $DIR/naked-functions-inline.rs:34:19
|
||||
|
|
||||
LL | #[naked]
|
||||
| -------- function marked with `#[naked]` here
|
||||
LL | #[cfg_attr(all(), inline(never))]
|
||||
| ^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0736`.
|
30
tests/ui/asm/naked-functions-instruction-set.rs
Normal file
30
tests/ui/asm/naked-functions-instruction-set.rs
Normal file
@ -0,0 +1,30 @@
|
||||
//@ compile-flags: --target armv5te-unknown-linux-gnueabi
|
||||
//@ needs-llvm-components: arm
|
||||
//@ needs-asm-support
|
||||
//@ build-pass
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(no_core, lang_items, rustc_attrs, naked_functions)]
|
||||
#![no_core]
|
||||
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! asm {
|
||||
() => {};
|
||||
}
|
||||
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
||||
|
||||
#[no_mangle]
|
||||
#[naked]
|
||||
#[instruction_set(arm::t32)]
|
||||
unsafe extern "C" fn test_thumb() {
|
||||
asm!("bx lr", options(noreturn));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[naked]
|
||||
#[instruction_set(arm::t32)]
|
||||
unsafe extern "C" fn test_arm() {
|
||||
asm!("bx lr", options(noreturn));
|
||||
}
|
39
tests/ui/asm/naked-functions-testattrs.rs
Normal file
39
tests/ui/asm/naked-functions-testattrs.rs
Normal file
@ -0,0 +1,39 @@
|
||||
//@ needs-asm-support
|
||||
//@ compile-flags: --test
|
||||
|
||||
#![allow(undefined_naked_function_abi)]
|
||||
#![feature(naked_functions)]
|
||||
#![feature(test)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
use std::arch::asm;
|
||||
|
||||
#[test]
|
||||
#[naked]
|
||||
//~^ ERROR [E0736]
|
||||
fn test_naked() {
|
||||
unsafe { asm!("", options(noreturn)) };
|
||||
}
|
||||
|
||||
#[should_panic]
|
||||
#[test]
|
||||
#[naked]
|
||||
//~^ ERROR [E0736]
|
||||
fn test_naked_should_panic() {
|
||||
unsafe { asm!("", options(noreturn)) };
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
#[naked]
|
||||
//~^ ERROR [E0736]
|
||||
fn test_naked_ignore() {
|
||||
unsafe { asm!("", options(noreturn)) };
|
||||
}
|
||||
|
||||
#[bench]
|
||||
#[naked]
|
||||
//~^ ERROR [E0736]
|
||||
fn bench_naked() {
|
||||
unsafe { asm!("", options(noreturn)) };
|
||||
}
|
35
tests/ui/asm/naked-functions-testattrs.stderr
Normal file
35
tests/ui/asm/naked-functions-testattrs.stderr
Normal file
@ -0,0 +1,35 @@
|
||||
error[E0736]: cannot use `#[naked]` with testing attributes
|
||||
--> $DIR/naked-functions-testattrs.rs:12:1
|
||||
|
|
||||
LL | #[test]
|
||||
| ------- function marked with testing attribute here
|
||||
LL | #[naked]
|
||||
| ^^^^^^^^ `#[naked]` is incompatible with testing attributes
|
||||
|
||||
error[E0736]: cannot use `#[naked]` with testing attributes
|
||||
--> $DIR/naked-functions-testattrs.rs:20:1
|
||||
|
|
||||
LL | #[test]
|
||||
| ------- function marked with testing attribute here
|
||||
LL | #[naked]
|
||||
| ^^^^^^^^ `#[naked]` is incompatible with testing attributes
|
||||
|
||||
error[E0736]: cannot use `#[naked]` with testing attributes
|
||||
--> $DIR/naked-functions-testattrs.rs:28:1
|
||||
|
|
||||
LL | #[test]
|
||||
| ------- function marked with testing attribute here
|
||||
LL | #[naked]
|
||||
| ^^^^^^^^ `#[naked]` is incompatible with testing attributes
|
||||
|
||||
error[E0736]: cannot use `#[naked]` with testing attributes
|
||||
--> $DIR/naked-functions-testattrs.rs:35:1
|
||||
|
|
||||
LL | #[bench]
|
||||
| -------- function marked with testing attribute here
|
||||
LL | #[naked]
|
||||
| ^^^^^^^^ `#[naked]` is incompatible with testing attributes
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0736`.
|
@ -3,7 +3,7 @@
|
||||
//@ ignore-spirv
|
||||
|
||||
#![feature(naked_functions)]
|
||||
#![feature(asm_const, asm_unwind)]
|
||||
#![feature(asm_const, asm_unwind, linkage)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
use std::arch::asm;
|
||||
@ -163,42 +163,6 @@ pub extern "C" fn valid_b() {
|
||||
}
|
||||
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn inline_none() {
|
||||
asm!("", options(noreturn));
|
||||
}
|
||||
|
||||
#[naked]
|
||||
#[inline]
|
||||
//~^ ERROR naked functions cannot be inlined
|
||||
pub unsafe extern "C" fn inline_hint() {
|
||||
asm!("", options(noreturn));
|
||||
}
|
||||
|
||||
#[naked]
|
||||
#[inline(always)]
|
||||
//~^ ERROR naked functions cannot be inlined
|
||||
pub unsafe extern "C" fn inline_always() {
|
||||
asm!("", options(noreturn));
|
||||
}
|
||||
|
||||
#[naked]
|
||||
#[inline(never)]
|
||||
//~^ ERROR naked functions cannot be inlined
|
||||
pub unsafe extern "C" fn inline_never() {
|
||||
asm!("", options(noreturn));
|
||||
}
|
||||
|
||||
#[naked]
|
||||
#[inline]
|
||||
//~^ ERROR naked functions cannot be inlined
|
||||
#[inline(always)]
|
||||
//~^ ERROR naked functions cannot be inlined
|
||||
#[inline(never)]
|
||||
//~^ ERROR naked functions cannot be inlined
|
||||
pub unsafe extern "C" fn inline_all() {
|
||||
asm!("", options(noreturn));
|
||||
}
|
||||
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn allow_compile_error(a: u32) -> u32 {
|
||||
compile_error!("this is a user specified error")
|
||||
@ -217,3 +181,71 @@ pub extern "C" fn valid_b() {
|
||||
asm!(invalid_syntax)
|
||||
//~^ ERROR asm template must be a string literal
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg_attr(target_pointer_width = "64", no_mangle)]
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn compatible_cfg_attributes() {
|
||||
asm!("", options(noreturn, att_syntax));
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[warn(dead_code)]
|
||||
#[deny(dead_code)]
|
||||
#[forbid(dead_code)]
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn compatible_diagnostic_attributes() {
|
||||
asm!("", options(noreturn, raw));
|
||||
}
|
||||
|
||||
#[deprecated = "test"]
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn compatible_deprecated_attributes() {
|
||||
asm!("", options(noreturn, raw));
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[must_use]
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
|
||||
asm!(
|
||||
"
|
||||
mov rax, 42
|
||||
ret
|
||||
",
|
||||
options(noreturn)
|
||||
)
|
||||
}
|
||||
|
||||
#[export_name = "exported_function_name"]
|
||||
#[link_section = ".custom_section"]
|
||||
#[no_mangle]
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn compatible_ffi_attributes_1() {
|
||||
asm!("", options(noreturn, raw));
|
||||
}
|
||||
|
||||
#[cold]
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn compatible_codegen_attributes() {
|
||||
asm!("", options(noreturn, raw));
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[target_feature(enable = "sse2")]
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn compatible_target_feature() {
|
||||
asm!("", options(noreturn));
|
||||
}
|
||||
|
||||
#[doc = "foo bar baz"]
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn compatible_doc_attributes() {
|
||||
asm!("", options(noreturn, raw));
|
||||
}
|
||||
|
||||
#[linkage = "external"]
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn compatible_linkage() {
|
||||
asm!("", options(noreturn, raw));
|
||||
}
|
||||
|
@ -5,19 +5,19 @@ LL | asm!("", options(readonly, nostack), options(pure));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^
|
||||
|
||||
error: this is a user specified error
|
||||
--> $DIR/naked-functions.rs:204:5
|
||||
--> $DIR/naked-functions.rs:168:5
|
||||
|
|
||||
LL | compile_error!("this is a user specified error")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this is a user specified error
|
||||
--> $DIR/naked-functions.rs:210:5
|
||||
--> $DIR/naked-functions.rs:174:5
|
||||
|
|
||||
LL | compile_error!("this is a user specified error");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: asm template must be a string literal
|
||||
--> $DIR/naked-functions.rs:217:10
|
||||
--> $DIR/naked-functions.rs:181:10
|
||||
|
|
||||
LL | asm!(invalid_syntax)
|
||||
| ^^^^^^^^^^^^^^
|
||||
@ -249,42 +249,6 @@ warning: Rust ABI is unsupported in naked functions
|
||||
LL | pub unsafe fn rust_abi() {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: naked functions cannot be inlined
|
||||
--> $DIR/naked-functions.rs:171:1
|
||||
|
|
||||
LL | #[inline]
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: naked functions cannot be inlined
|
||||
--> $DIR/naked-functions.rs:178:1
|
||||
|
|
||||
LL | #[inline(always)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: naked functions cannot be inlined
|
||||
--> $DIR/naked-functions.rs:185:1
|
||||
|
|
||||
LL | #[inline(never)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: naked functions cannot be inlined
|
||||
--> $DIR/naked-functions.rs:192:1
|
||||
|
|
||||
LL | #[inline]
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: naked functions cannot be inlined
|
||||
--> $DIR/naked-functions.rs:194:1
|
||||
|
|
||||
LL | #[inline(always)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: naked functions cannot be inlined
|
||||
--> $DIR/naked-functions.rs:196:1
|
||||
|
|
||||
LL | #[inline(never)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 33 previous errors; 2 warnings emitted
|
||||
error: aborting due to 27 previous errors; 2 warnings emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0787`.
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
use std::arch::asm;
|
||||
|
||||
#[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]`
|
||||
#[track_caller] //~ ERROR [E0736]
|
||||
//~^ ERROR `#[track_caller]` requires Rust ABI
|
||||
#[naked]
|
||||
extern "C" fn f() {
|
||||
@ -15,7 +15,7 @@ extern "C" fn f() {
|
||||
struct S;
|
||||
|
||||
impl S {
|
||||
#[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]`
|
||||
#[track_caller] //~ ERROR [E0736]
|
||||
//~^ ERROR `#[track_caller]` requires Rust ABI
|
||||
#[naked]
|
||||
extern "C" fn g() {
|
||||
|
@ -1,14 +1,20 @@
|
||||
error[E0736]: cannot use `#[track_caller]` with `#[naked]`
|
||||
error[E0736]: attribute incompatible with `#[naked]`
|
||||
--> $DIR/error-with-naked.rs:6:1
|
||||
|
|
||||
LL | #[track_caller]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^ the `track_caller` attribute is incompatible with `#[naked]`
|
||||
LL |
|
||||
LL | #[naked]
|
||||
| -------- function marked with `#[naked]` here
|
||||
|
||||
error[E0736]: cannot use `#[track_caller]` with `#[naked]`
|
||||
error[E0736]: attribute incompatible with `#[naked]`
|
||||
--> $DIR/error-with-naked.rs:18:5
|
||||
|
|
||||
LL | #[track_caller]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^ the `track_caller` attribute is incompatible with `#[naked]`
|
||||
LL |
|
||||
LL | #[naked]
|
||||
| -------- function marked with `#[naked]` here
|
||||
|
||||
error[E0737]: `#[track_caller]` requires Rust ABI
|
||||
--> $DIR/error-with-naked.rs:6:1
|
||||
|
Loading…
Reference in New Issue
Block a user