diff options
| author | Nathaniel McCallum <nathaniel@congru.us> | 2021-08-02 15:03:43 -0400 |
|---|---|---|
| committer | Nathaniel McCallum <nathaniel@congru.us> | 2021-08-02 21:49:51 -0400 |
| commit | 157e0a0e8f68ab997b320a2d61c2d8ad20d5ce86 (patch) | |
| tree | 7d397100e11380c2f4d0b2c2877c4e06e7ed160e | |
| parent | 6be8a06bcf2e7c45db2f9e3dd3c9c0e282562a93 (diff) | |
| download | rust-157e0a0e8f68ab997b320a2d61c2d8ad20d5ce86.tar.gz rust-157e0a0e8f68ab997b320a2d61c2d8ad20d5ce86.zip | |
Validate that naked functions are never inlined
Reject all uses of the inline attribute on naked functions. rust-lang/rfcs#2774 rust-lang/rfcs#2972
| -rw-r--r-- | compiler/rustc_lint_defs/src/builtin.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/naked_functions.rs | 12 | ||||
| -rw-r--r-- | src/test/ui/asm/naked-functions.rs | 43 | ||||
| -rw-r--r-- | src/test/ui/asm/naked-functions.stderr | 56 |
4 files changed, 112 insertions, 2 deletions
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 7195c41eae9..b1948ae072b 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2720,6 +2720,9 @@ declare_lint! { /// The asm block must not contain any operands other than `const` and /// `sym`. Additionally, naked function should specify a non-Rust ABI. /// + /// Naked functions cannot be inlined. All forms of the `inline` attribute + /// are prohibited. + /// /// While other definitions of naked functions were previously accepted, /// they are unsupported and might not work reliably. This is a /// [future-incompatible] lint that will transition into hard error in diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index 89bc2e1a987..e05ec205b65 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -1,6 +1,6 @@ //! Checks validity of naked functions. -use rustc_ast::InlineAsmOptions; +use rustc_ast::{Attribute, InlineAsmOptions}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{ErasedMap, FnKind, NestedVisitorMap, Visitor}; @@ -70,10 +70,20 @@ impl<'tcx> Visitor<'tcx> for CheckNakedFunctions<'tcx> { check_no_patterns(self.tcx, body.params); check_no_parameters_use(self.tcx, body); check_asm(self.tcx, hir_id, body, span); + check_inline(self.tcx, hir_id, attrs); } } } +/// Check that the function isn't inlined. +fn check_inline(tcx: TyCtxt<'_>, hir_id: HirId, attrs: &[Attribute]) { + for attr in attrs.iter().filter(|attr| attr.has_name(sym::inline)) { + tcx.struct_span_lint_hir(UNSUPPORTED_NAKED_FUNCTIONS, hir_id, attr.span, |lint| { + lint.build("naked functions cannot be inlined").emit(); + }); + } +} + /// 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 { diff --git a/src/test/ui/asm/naked-functions.rs b/src/test/ui/asm/naked-functions.rs index a46ca4544a6..7075995c2cf 100644 --- a/src/test/ui/asm/naked-functions.rs +++ b/src/test/ui/asm/naked-functions.rs @@ -167,3 +167,46 @@ pub unsafe extern "C" fn valid_c() { pub unsafe extern "C" fn valid_att_syntax() { asm!("", options(noreturn, att_syntax)); } + +#[naked] +pub unsafe extern "C" fn inline_none() { + asm!("", options(noreturn)); +} + +#[naked] +#[inline] +//~^ WARN naked functions cannot be inlined +//~| WARN this was previously accepted +pub unsafe extern "C" fn inline_hint() { + asm!("", options(noreturn)); +} + +#[naked] +#[inline(always)] +//~^ WARN naked functions cannot be inlined +//~| WARN this was previously accepted +pub unsafe extern "C" fn inline_always() { + asm!("", options(noreturn)); +} + +#[naked] +#[inline(never)] +//~^ WARN naked functions cannot be inlined +//~| WARN this was previously accepted +pub unsafe extern "C" fn inline_never() { + asm!("", options(noreturn)); +} + +#[naked] +#[inline] +//~^ WARN naked functions cannot be inlined +//~| WARN this was previously accepted +#[inline(always)] +//~^ WARN naked functions cannot be inlined +//~| WARN this was previously accepted +#[inline(never)] +//~^ WARN naked functions cannot be inlined +//~| WARN this was previously accepted +pub unsafe extern "C" fn inline_all() { + asm!("", options(noreturn)); +} diff --git a/src/test/ui/asm/naked-functions.stderr b/src/test/ui/asm/naked-functions.stderr index 9a82da8d90d..2a186a69ff4 100644 --- a/src/test/ui/asm/naked-functions.stderr +++ b/src/test/ui/asm/naked-functions.stderr @@ -296,5 +296,59 @@ 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> -error: aborting due to 8 previous errors; 19 warnings emitted +warning: naked functions cannot be inlined + --> $DIR/naked-functions.rs:177:1 + | +LL | #[inline] + | ^^^^^^^^^ + | + = 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 + --> $DIR/naked-functions.rs:185:1 + | +LL | #[inline(always)] + | ^^^^^^^^^^^^^^^^^ + | + = 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 + --> $DIR/naked-functions.rs:193:1 + | +LL | #[inline(never)] + | ^^^^^^^^^^^^^^^^ + | + = 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 + --> $DIR/naked-functions.rs:201:1 + | +LL | #[inline] + | ^^^^^^^^^ + | + = 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 + --> $DIR/naked-functions.rs:204:1 + | +LL | #[inline(always)] + | ^^^^^^^^^^^^^^^^^ + | + = 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 + --> $DIR/naked-functions.rs:207:1 + | +LL | #[inline(never)] + | ^^^^^^^^^^^^^^^^ + | + = 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> + +error: aborting due to 8 previous errors; 25 warnings emitted |
