From 8866af388497e9ed3254147c015379d5d6cdb054 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 26 Mar 2025 19:44:53 +0100 Subject: [PATCH] Add `naked_functions_rustic_abi` feature gate --- compiler/rustc_feature/src/unstable.rs | 2 ++ compiler/rustc_lint/src/lib.rs | 5 +++ compiler/rustc_lint_defs/src/builtin.rs | 34 ------------------- compiler/rustc_passes/messages.ftl | 3 -- compiler/rustc_passes/src/check_attr.rs | 15 ++++++++ compiler/rustc_passes/src/errors.rs | 4 --- compiler/rustc_passes/src/naked_functions.rs | 33 ++++-------------- compiler/rustc_span/src/symbol.rs | 1 + tests/ui/asm/naked-functions-rustic-abi.rs | 27 +++++++++++++++ tests/ui/asm/naked-functions-testattrs.rs | 9 +++-- tests/ui/asm/naked-functions-testattrs.stderr | 8 ++--- tests/ui/asm/naked-functions.rs | 12 ------- tests/ui/asm/naked-functions.stderr | 22 +++--------- ...feature-gate-naked_functions_rustic_abi.rs | 26 ++++++++++++++ ...ure-gate-naked_functions_rustic_abi.stderr | 33 ++++++++++++++++++ .../undefined_naked_function_abi.rs | 5 +++ .../undefined_naked_function_abi.stderr | 10 ++++++ 17 files changed, 142 insertions(+), 107 deletions(-) create mode 100644 tests/ui/asm/naked-functions-rustic-abi.rs create mode 100644 tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.rs create mode 100644 tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.stderr create mode 100644 tests/ui/lint/removed-lints/undefined_naked_function_abi.rs create mode 100644 tests/ui/lint/removed-lints/undefined_naked_function_abi.stderr diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 72468dd4714d7..e0af871d3fd4e 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -566,6 +566,8 @@ declare_features! ( (incomplete, mut_ref, "1.79.0", Some(123076)), /// Allows using `#[naked]` on functions. (unstable, naked_functions, "1.9.0", Some(90957)), + /// Allows using `#[naked]` on `extern "Rust"` functions. + (unstable, naked_functions_rustic_abi, "CURRENT_RUSTC_VERSION", Some(138997)), /// Allows using `#[target_feature(enable = "...")]` on `#[naked]` on functions. (unstable, naked_functions_target_feature, "1.86.0", Some(138568)), /// Allows specifying the as-needed link modifier diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index c38a754001811..1863ba8f8fb6f 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -604,6 +604,11 @@ fn register_builtins(store: &mut LintStore) { "converted into hard error, see issue #127323 \ for more information", ); + store.register_removed( + "undefined_naked_function_abi", + "converted into hard error, see PR #139001 \ + for more information", + ); } fn register_internals(store: &mut LintStore) { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 8a761a0a0969b..b25d2a30681c0 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -110,7 +110,6 @@ declare_lint_pass! { UNCONDITIONAL_PANIC, UNCONDITIONAL_RECURSION, UNCOVERED_PARAM_IN_PROJECTION, - UNDEFINED_NAKED_FUNCTION_ABI, UNEXPECTED_CFGS, UNFULFILLED_LINT_EXPECTATIONS, UNINHABITED_STATIC, @@ -2830,39 +2829,6 @@ 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(asm_experimental_arch, naked_functions)] - /// - /// use std::arch::naked_asm; - /// - /// #[naked] - /// pub fn default_abi() -> u32 { - /// unsafe { naked_asm!(""); } - /// } - /// - /// #[naked] - /// pub extern "Rust" fn rust_abi() -> u32 { - /// unsafe { naked_asm!(""); } - /// } - /// ``` - /// - /// {{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 `ineffective_unstable_trait_impl` lint detects `#[unstable]` attributes which are not used. /// diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 06398dd4f725b..18cbbad92b6c3 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -738,9 +738,6 @@ passes_trait_impl_const_stable = passes_transparent_incompatible = transparent {$target} cannot have other repr hints -passes_undefined_naked_function_abi = - Rust ABI is unsupported in naked functions - passes_unknown_external_lang_item = unknown external lang item: `{$lang_item}` diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 9238c73cdb113..50ce206412937 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -607,6 +607,21 @@ impl<'tcx> CheckAttrVisitor<'tcx> { match target { Target::Fn | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => { + let fn_sig = self.tcx.hir_node(hir_id).fn_sig().unwrap(); + let abi = fn_sig.header.abi; + if abi.is_rustic_abi() && !self.tcx.features().naked_functions_rustic_abi() { + feature_err( + &self.tcx.sess, + sym::naked_functions_rustic_abi, + fn_sig.span, + format!( + "`#[naked]` is currently unstable on `extern \"{}\"` functions", + abi.as_str() + ), + ) + .emit(); + } + for other_attr in attrs { // this covers "sugared doc comments" of the form `/// ...` // it does not cover `#[doc = "..."]`, which is handled below diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 0ee17430aab8e..536cb96bf4664 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1197,10 +1197,6 @@ pub(crate) struct UnlabeledCfInWhileCondition<'a> { pub cf_type: &'a str, } -#[derive(LintDiagnostic)] -#[diag(passes_undefined_naked_function_abi)] -pub(crate) struct UndefinedNakedFunctionAbi; - #[derive(Diagnostic)] #[diag(passes_no_patterns)] pub(crate) struct NoPatterns { diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index d35aedf9a5647..3c9f8b72c3635 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -1,6 +1,5 @@ //! Checks validity of naked functions. -use rustc_abi::ExternAbi; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{LocalDefId, LocalModDefId}; @@ -10,12 +9,11 @@ use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_middle::query::Providers; use rustc_middle::span_bug; use rustc_middle::ty::TyCtxt; -use rustc_session::lint::builtin::UNDEFINED_NAKED_FUNCTION_ABI; use rustc_span::{Span, sym}; use crate::errors::{ NakedAsmOutsideNakedFn, NakedFunctionsAsmBlock, NakedFunctionsMustNakedAsm, NoPatterns, - ParamsNotAllowed, UndefinedNakedFunctionAbi, + ParamsNotAllowed, }; pub(crate) fn provide(providers: &mut Providers) { @@ -29,26 +27,21 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { continue; } - let (fn_header, body_id) = match tcx.hir_node_by_def_id(def_id) { + let body = match tcx.hir_node_by_def_id(def_id) { hir::Node::Item(hir::Item { - kind: hir::ItemKind::Fn { sig, body: body_id, .. }, - .. + kind: hir::ItemKind::Fn { body: body_id, .. }, .. }) | hir::Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), + kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body_id)), .. }) | hir::Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::Fn(sig, body_id), - .. - }) => (sig.header, *body_id), + kind: hir::ImplItemKind::Fn(_, body_id), .. + }) => tcx.hir_body(*body_id), _ => continue, }; - let body = tcx.hir_body(body_id); - if tcx.has_attr(def_id, sym::naked) { - check_abi(tcx, def_id, fn_header.abi); check_no_patterns(tcx, body.params); check_no_parameters_use(tcx, body); check_asm(tcx, def_id, body); @@ -60,20 +53,6 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { } } -/// Checks that function uses non-Rust ABI. -fn check_abi(tcx: TyCtxt<'_>, def_id: LocalDefId, abi: ExternAbi) { - if abi == ExternAbi::Rust { - let hir_id = tcx.local_def_id_to_hir_id(def_id); - let span = tcx.def_span(def_id); - tcx.emit_node_span_lint( - UNDEFINED_NAKED_FUNCTION_ABI, - hir_id, - span, - UndefinedNakedFunctionAbi, - ); - } -} - /// Checks that parameters don't use patterns. Mirrors the checks for function declarations. fn check_no_patterns(tcx: TyCtxt<'_>, params: &[hir::Param<'_>]) { for param in params { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3e4742439655a..5906b242dda65 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1387,6 +1387,7 @@ symbols! { naked, naked_asm, naked_functions, + naked_functions_rustic_abi, naked_functions_target_feature, name, names, diff --git a/tests/ui/asm/naked-functions-rustic-abi.rs b/tests/ui/asm/naked-functions-rustic-abi.rs new file mode 100644 index 0000000000000..b654d38ccc1a6 --- /dev/null +++ b/tests/ui/asm/naked-functions-rustic-abi.rs @@ -0,0 +1,27 @@ +//@ revisions: x86_64 aarch64 +// +//@[aarch64] only-aarch64 +//@[x86_64] only-x86_64 +// +//@ build-pass +//@ needs-asm-support + +#![feature(naked_functions, naked_functions_rustic_abi, rust_cold_cc)] +#![crate_type = "lib"] + +use std::arch::{asm, naked_asm}; + +#[naked] +pub unsafe fn rust_implicit() { + naked_asm!("ret"); +} + +#[naked] +pub unsafe extern "Rust" fn rust_explicit() { + naked_asm!("ret"); +} + +#[naked] +pub unsafe extern "rust-cold" fn rust_cold() { + naked_asm!("ret"); +} diff --git a/tests/ui/asm/naked-functions-testattrs.rs b/tests/ui/asm/naked-functions-testattrs.rs index 7e373270e9fc6..ad31876a77a59 100644 --- a/tests/ui/asm/naked-functions-testattrs.rs +++ b/tests/ui/asm/naked-functions-testattrs.rs @@ -1,7 +1,6 @@ //@ needs-asm-support //@ compile-flags: --test -#![allow(undefined_naked_function_abi)] #![feature(naked_functions)] #![feature(test)] #![crate_type = "lib"] @@ -11,7 +10,7 @@ use std::arch::naked_asm; #[test] #[naked] //~^ ERROR [E0736] -fn test_naked() { +extern "C" fn test_naked() { unsafe { naked_asm!("") }; } @@ -19,7 +18,7 @@ fn test_naked() { #[test] #[naked] //~^ ERROR [E0736] -fn test_naked_should_panic() { +extern "C" fn test_naked_should_panic() { unsafe { naked_asm!("") }; } @@ -27,13 +26,13 @@ fn test_naked_should_panic() { #[test] #[naked] //~^ ERROR [E0736] -fn test_naked_ignore() { +extern "C" fn test_naked_ignore() { unsafe { naked_asm!("") }; } #[bench] #[naked] //~^ ERROR [E0736] -fn bench_naked() { +extern "C" fn bench_naked() { unsafe { naked_asm!("") }; } diff --git a/tests/ui/asm/naked-functions-testattrs.stderr b/tests/ui/asm/naked-functions-testattrs.stderr index 4dabe41964a57..0f0bb91b95413 100644 --- a/tests/ui/asm/naked-functions-testattrs.stderr +++ b/tests/ui/asm/naked-functions-testattrs.stderr @@ -1,5 +1,5 @@ error[E0736]: cannot use `#[naked]` with testing attributes - --> $DIR/naked-functions-testattrs.rs:12:1 + --> $DIR/naked-functions-testattrs.rs:11:1 | LL | #[test] | ------- function marked with testing attribute here @@ -7,7 +7,7 @@ LL | #[naked] | ^^^^^^^^ `#[naked]` is incompatible with testing attributes error[E0736]: cannot use `#[naked]` with testing attributes - --> $DIR/naked-functions-testattrs.rs:20:1 + --> $DIR/naked-functions-testattrs.rs:19:1 | LL | #[test] | ------- function marked with testing attribute here @@ -15,7 +15,7 @@ LL | #[naked] | ^^^^^^^^ `#[naked]` is incompatible with testing attributes error[E0736]: cannot use `#[naked]` with testing attributes - --> $DIR/naked-functions-testattrs.rs:28:1 + --> $DIR/naked-functions-testattrs.rs:27:1 | LL | #[test] | ------- function marked with testing attribute here @@ -23,7 +23,7 @@ LL | #[naked] | ^^^^^^^^ `#[naked]` is incompatible with testing attributes error[E0736]: cannot use `#[naked]` with testing attributes - --> $DIR/naked-functions-testattrs.rs:35:1 + --> $DIR/naked-functions-testattrs.rs:34:1 | LL | #[bench] | -------- function marked with testing attribute here diff --git a/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs index 3d4d414539c16..5bf2e2a3abd06 100644 --- a/tests/ui/asm/naked-functions.rs +++ b/tests/ui/asm/naked-functions.rs @@ -122,18 +122,6 @@ unsafe extern "C" fn invalid_may_unwind() { //~^ ERROR the `may_unwind` option cannot be used with `naked_asm!` } -#[naked] -pub unsafe fn default_abi() { - //~^ WARN Rust ABI is unsupported in naked functions - naked_asm!(""); -} - -#[naked] -pub unsafe fn rust_abi() { - //~^ WARN Rust ABI is unsupported in naked functions - naked_asm!(""); -} - #[naked] pub extern "C" fn valid_a() -> T { unsafe { diff --git a/tests/ui/asm/naked-functions.stderr b/tests/ui/asm/naked-functions.stderr index 0898f3620f24f..0a55bb9cd8370 100644 --- a/tests/ui/asm/naked-functions.stderr +++ b/tests/ui/asm/naked-functions.stderr @@ -53,19 +53,19 @@ LL | naked_asm!("", options(may_unwind)); | ^^^^^^^^^^ the `may_unwind` option is not meaningful for global-scoped inline assembly error: this is a user specified error - --> $DIR/naked-functions.rs:169:5 + --> $DIR/naked-functions.rs:157:5 | LL | compile_error!("this is a user specified error") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this is a user specified error - --> $DIR/naked-functions.rs:175:5 + --> $DIR/naked-functions.rs:163:5 | LL | compile_error!("this is a user specified error"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: asm template must be a string literal - --> $DIR/naked-functions.rs:182:16 + --> $DIR/naked-functions.rs:170:16 | LL | naked_asm!(invalid_syntax) | ^^^^^^^^^^^^^^ @@ -175,20 +175,6 @@ LL | LL | *&y | --- not allowed in naked functions -warning: Rust ABI is unsupported in naked functions - --> $DIR/naked-functions.rs:126:1 - | -LL | pub unsafe fn default_abi() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(undefined_naked_function_abi)]` on by default - -warning: Rust ABI is unsupported in naked functions - --> $DIR/naked-functions.rs:132:1 - | -LL | pub unsafe fn rust_abi() { - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 25 previous errors; 2 warnings emitted +error: aborting due to 25 previous errors For more information about this error, try `rustc --explain E0787`. diff --git a/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.rs b/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.rs new file mode 100644 index 0000000000000..c91d833994414 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.rs @@ -0,0 +1,26 @@ +//@ needs-asm-support +//@ only-x86_64 + +#![feature(naked_functions, rust_cold_cc)] + +use std::arch::naked_asm; + +#[naked] +pub unsafe fn rust_implicit() { + //~^ ERROR `#[naked]` is currently unstable on `extern "Rust"` functions + naked_asm!("ret"); +} + +#[naked] +pub unsafe extern "Rust" fn rust_explicit() { + //~^ ERROR `#[naked]` is currently unstable on `extern "Rust"` functions + naked_asm!("ret"); +} + +#[naked] +pub unsafe extern "rust-cold" fn rust_cold() { + //~^ ERROR `#[naked]` is currently unstable on `extern "rust-cold"` functions + naked_asm!("ret"); +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.stderr b/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.stderr new file mode 100644 index 0000000000000..ba45e15ec86b6 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.stderr @@ -0,0 +1,33 @@ +error[E0658]: `#[naked]` is currently unstable on `extern "Rust"` functions + --> $DIR/feature-gate-naked_functions_rustic_abi.rs:9:1 + | +LL | pub unsafe fn rust_implicit() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #138997 for more information + = help: add `#![feature(naked_functions_rustic_abi)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `#[naked]` is currently unstable on `extern "Rust"` functions + --> $DIR/feature-gate-naked_functions_rustic_abi.rs:15:1 + | +LL | pub unsafe extern "Rust" fn rust_explicit() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #138997 for more information + = help: add `#![feature(naked_functions_rustic_abi)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `#[naked]` is currently unstable on `extern "rust-cold"` functions + --> $DIR/feature-gate-naked_functions_rustic_abi.rs:21:1 + | +LL | pub unsafe extern "rust-cold" fn rust_cold() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #138997 for more information + = help: add `#![feature(naked_functions_rustic_abi)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/lint/removed-lints/undefined_naked_function_abi.rs b/tests/ui/lint/removed-lints/undefined_naked_function_abi.rs new file mode 100644 index 0000000000000..cf3ac66ac86d4 --- /dev/null +++ b/tests/ui/lint/removed-lints/undefined_naked_function_abi.rs @@ -0,0 +1,5 @@ +//@ check-pass + +#![deny(undefined_naked_function_abi)] +//~^ WARN lint `undefined_naked_function_abi` has been removed +fn main() {} diff --git a/tests/ui/lint/removed-lints/undefined_naked_function_abi.stderr b/tests/ui/lint/removed-lints/undefined_naked_function_abi.stderr new file mode 100644 index 0000000000000..5a546688beb5c --- /dev/null +++ b/tests/ui/lint/removed-lints/undefined_naked_function_abi.stderr @@ -0,0 +1,10 @@ +warning: lint `undefined_naked_function_abi` has been removed: converted into hard error, see PR #139001 for more information + --> $DIR/undefined_naked_function_abi.rs:3:9 + | +LL | #![deny(undefined_naked_function_abi)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(renamed_and_removed_lints)]` on by default + +warning: 1 warning emitted +