From ba9afb58b330058dc74171ba5cf68fce8d78d02e Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Wed, 4 Aug 2021 15:00:49 -0400 Subject: [PATCH 1/2] 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 --- compiler/rustc_lint_defs/src/builtin.rs | 34 +++++++++++++++++++- compiler/rustc_passes/src/naked_functions.rs | 3 +- src/test/ui/asm/naked-functions.rs | 2 -- src/test/ui/asm/naked-functions.stderr | 20 +++++------- 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 9b1ee53df23bd..76f5f4097d9a8 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2691,6 +2691,38 @@ declare_lint! { "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! { /// The `unsupported_naked_functions` lint detects naked function /// definitions that are unsupported but were previously accepted. @@ -2701,7 +2733,7 @@ declare_lint! { /// #![feature(naked_functions)] /// /// #[naked] - /// pub fn f() -> u32 { + /// pub extern "sysv64" fn f() -> u32 { /// 42 /// } /// ``` diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index e05ec205b65b8..899503cc556e5 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -7,6 +7,7 @@ use rustc_hir::intravisit::{ErasedMap, FnKind, NestedVisitorMap, Visitor}; use rustc_hir::{ExprKind, HirId, InlineAsmOperand, StmtKind}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; +use rustc_session::lint::builtin::UNDEFINED_NAKED_FUNCTION_ABI; use rustc_session::lint::builtin::UNSUPPORTED_NAKED_FUNCTIONS; use rustc_span::symbol::sym; 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. fn check_abi(tcx: TyCtxt<'_>, hir_id: HirId, abi: Abi, fn_ident_span: Span) { 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(); }); } diff --git a/src/test/ui/asm/naked-functions.rs b/src/test/ui/asm/naked-functions.rs index 7075995c2cfff..900f4443a1fd6 100644 --- a/src/test/ui/asm/naked-functions.rs +++ b/src/test/ui/asm/naked-functions.rs @@ -134,14 +134,12 @@ unsafe extern "C" fn invalid_options_continued() { #[naked] pub unsafe fn default_abi() { //~^ WARN Rust ABI is unsupported in naked functions - //~| WARN this was previously accepted asm!("", options(noreturn)); } #[naked] pub unsafe extern "Rust" fn rust_abi() { //~^ WARN Rust ABI is unsupported in naked functions - //~| WARN this was previously accepted asm!("", options(noreturn)); } diff --git a/src/test/ui/asm/naked-functions.stderr b/src/test/ui/asm/naked-functions.stderr index 2a186a69ff460..231a6239cbde5 100644 --- a/src/test/ui/asm/naked-functions.stderr +++ b/src/test/ui/asm/naked-functions.stderr @@ -284,20 +284,16 @@ warning: Rust ABI is unsupported in naked functions 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: for more information, see issue #32408 + = note: `#[warn(undefined_naked_function_abi)]` on by default 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() { | ^^^^^^^^ - | - = 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 warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:177:1 + --> $DIR/naked-functions.rs:175:1 | LL | #[inline] | ^^^^^^^^^ @@ -306,7 +302,7 @@ LL | #[inline] = note: for more information, see issue #32408 warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:185:1 + --> $DIR/naked-functions.rs:183:1 | LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ @@ -315,7 +311,7 @@ LL | #[inline(always)] = note: for more information, see issue #32408 warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:193:1 + --> $DIR/naked-functions.rs:191:1 | LL | #[inline(never)] | ^^^^^^^^^^^^^^^^ @@ -324,7 +320,7 @@ LL | #[inline(never)] = note: for more information, see issue #32408 warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:201:1 + --> $DIR/naked-functions.rs:199:1 | LL | #[inline] | ^^^^^^^^^ @@ -333,7 +329,7 @@ LL | #[inline] = note: for more information, see issue #32408 warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:204:1 + --> $DIR/naked-functions.rs:202:1 | LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ @@ -342,7 +338,7 @@ LL | #[inline(always)] = note: for more information, see issue #32408 warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:207:1 + --> $DIR/naked-functions.rs:205:1 | LL | #[inline(never)] | ^^^^^^^^^^^^^^^^ From 49685377805e9c87d00aa1d8b8cece3de2dc8319 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Sat, 7 Aug 2021 11:17:03 -0400 Subject: [PATCH 2/2] Fix naked function test run on non-x86_64 --- compiler/rustc_lint_defs/src/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 76f5f4097d9a8..106afa3495c04 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2733,7 +2733,7 @@ declare_lint! { /// #![feature(naked_functions)] /// /// #[naked] - /// pub extern "sysv64" fn f() -> u32 { + /// pub extern "C" fn f() -> u32 { /// 42 /// } /// ```