Move naked function ABI check to its own lint

This check was previously categorized under the lint named
`UNSUPPORTED_NAKED_FUNCTIONS`. That lint is future incompatible and will
be turned into an error in a future release. However, as defined in the
Constrained Naked Functions RFC, this check should only be a warning.
This is because it is possible for a naked function to be implemented in
such a way that it does not break even the undefined ABI. For example, a
`jmp` to a `const`.

Therefore, this patch defines a new lint named
`UNDEFINED_NAKED_FUNCTION_ABI` which contains just this single check.
Unlike `UNSUPPORTED_NAKED_FUNCTIONS`, `UNDEFINED_NAKED_FUNCTION_ABI`
will not be converted to an error in the future.

rust-lang/rfcs#2774
rust-lang/rfcs#2972
This commit is contained in:
Nathaniel McCallum 2021-08-04 15:00:49 -04:00
parent 6fe0886723
commit ba9afb58b3
4 changed files with 43 additions and 16 deletions

View File

@ -2691,6 +2691,38 @@ declare_lint! {
"detects deprecation attributes with no effect", "detects deprecation attributes with no effect",
} }
declare_lint! {
/// The `undefined_naked_function_abi` lint detects naked function definitions that
/// either do not specify an ABI or specify the Rust ABI.
///
/// ### Example
///
/// ```rust
/// #![feature(naked_functions)]
/// #![feature(asm)]
///
/// #[naked]
/// pub fn default_abi() -> u32 {
/// unsafe { asm!("", options(noreturn)); }
/// }
///
/// #[naked]
/// pub extern "Rust" fn rust_abi() -> u32 {
/// unsafe { asm!("", options(noreturn)); }
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The Rust ABI is currently undefined. Therefore, naked functions should
/// specify a non-Rust ABI.
pub UNDEFINED_NAKED_FUNCTION_ABI,
Warn,
"undefined naked function ABI"
}
declare_lint! { declare_lint! {
/// The `unsupported_naked_functions` lint detects naked function /// The `unsupported_naked_functions` lint detects naked function
/// definitions that are unsupported but were previously accepted. /// definitions that are unsupported but were previously accepted.
@ -2701,7 +2733,7 @@ declare_lint! {
/// #![feature(naked_functions)] /// #![feature(naked_functions)]
/// ///
/// #[naked] /// #[naked]
/// pub fn f() -> u32 { /// pub extern "sysv64" fn f() -> u32 {
/// 42 /// 42
/// } /// }
/// ``` /// ```

View File

@ -7,6 +7,7 @@ use rustc_hir::intravisit::{ErasedMap, FnKind, NestedVisitorMap, Visitor};
use rustc_hir::{ExprKind, HirId, InlineAsmOperand, StmtKind}; use rustc_hir::{ExprKind, HirId, InlineAsmOperand, StmtKind};
use rustc_middle::ty::query::Providers; use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::UNDEFINED_NAKED_FUNCTION_ABI;
use rustc_session::lint::builtin::UNSUPPORTED_NAKED_FUNCTIONS; use rustc_session::lint::builtin::UNSUPPORTED_NAKED_FUNCTIONS;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::Span; use rustc_span::Span;
@ -87,7 +88,7 @@ fn check_inline(tcx: TyCtxt<'_>, hir_id: HirId, attrs: &[Attribute]) {
/// Checks that function uses non-Rust ABI. /// Checks that function uses non-Rust ABI.
fn check_abi(tcx: TyCtxt<'_>, hir_id: HirId, abi: Abi, fn_ident_span: Span) { fn check_abi(tcx: TyCtxt<'_>, hir_id: HirId, abi: Abi, fn_ident_span: Span) {
if abi == Abi::Rust { if abi == Abi::Rust {
tcx.struct_span_lint_hir(UNSUPPORTED_NAKED_FUNCTIONS, hir_id, fn_ident_span, |lint| { tcx.struct_span_lint_hir(UNDEFINED_NAKED_FUNCTION_ABI, hir_id, fn_ident_span, |lint| {
lint.build("Rust ABI is unsupported in naked functions").emit(); lint.build("Rust ABI is unsupported in naked functions").emit();
}); });
} }

View File

@ -134,14 +134,12 @@ unsafe extern "C" fn invalid_options_continued() {
#[naked] #[naked]
pub unsafe fn default_abi() { pub unsafe fn default_abi() {
//~^ WARN Rust ABI is unsupported in naked functions //~^ WARN Rust ABI is unsupported in naked functions
//~| WARN this was previously accepted
asm!("", options(noreturn)); asm!("", options(noreturn));
} }
#[naked] #[naked]
pub unsafe extern "Rust" fn rust_abi() { pub unsafe extern "Rust" fn rust_abi() {
//~^ WARN Rust ABI is unsupported in naked functions //~^ WARN Rust ABI is unsupported in naked functions
//~| WARN this was previously accepted
asm!("", options(noreturn)); asm!("", options(noreturn));
} }

View File

@ -284,20 +284,16 @@ warning: Rust ABI is unsupported in naked functions
LL | pub unsafe fn default_abi() { LL | pub unsafe fn default_abi() {
| ^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: `#[warn(undefined_naked_function_abi)]` on by default
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: Rust ABI is unsupported in naked functions warning: Rust ABI is unsupported in naked functions
--> $DIR/naked-functions.rs:142:29 --> $DIR/naked-functions.rs:141:29
| |
LL | pub unsafe extern "Rust" fn rust_abi() { LL | pub unsafe extern "Rust" fn rust_abi() {
| ^^^^^^^^ | ^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions cannot be inlined warning: naked functions cannot be inlined
--> $DIR/naked-functions.rs:177:1 --> $DIR/naked-functions.rs:175:1
| |
LL | #[inline] LL | #[inline]
| ^^^^^^^^^ | ^^^^^^^^^
@ -306,7 +302,7 @@ LL | #[inline]
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408> = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions cannot be inlined warning: naked functions cannot be inlined
--> $DIR/naked-functions.rs:185:1 --> $DIR/naked-functions.rs:183:1
| |
LL | #[inline(always)] LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
@ -315,7 +311,7 @@ LL | #[inline(always)]
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408> = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions cannot be inlined warning: naked functions cannot be inlined
--> $DIR/naked-functions.rs:193:1 --> $DIR/naked-functions.rs:191:1
| |
LL | #[inline(never)] LL | #[inline(never)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
@ -324,7 +320,7 @@ LL | #[inline(never)]
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408> = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions cannot be inlined warning: naked functions cannot be inlined
--> $DIR/naked-functions.rs:201:1 --> $DIR/naked-functions.rs:199:1
| |
LL | #[inline] LL | #[inline]
| ^^^^^^^^^ | ^^^^^^^^^
@ -333,7 +329,7 @@ LL | #[inline]
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408> = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions cannot be inlined warning: naked functions cannot be inlined
--> $DIR/naked-functions.rs:204:1 --> $DIR/naked-functions.rs:202:1
| |
LL | #[inline(always)] LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
@ -342,7 +338,7 @@ LL | #[inline(always)]
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408> = note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions cannot be inlined warning: naked functions cannot be inlined
--> $DIR/naked-functions.rs:207:1 --> $DIR/naked-functions.rs:205:1
| |
LL | #[inline(never)] LL | #[inline(never)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^