about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2021-08-03 19:07:44 +0900
committerGitHub <noreply@github.com>2021-08-03 19:07:44 +0900
commita14b283022af5bdf7507f37e31638fc64ecca298 (patch)
tree58b9a748675b0e5b3e479a6e05c140c77247bb0d
parentf69daa261742f447f269d1ee9f814dfd5cb4eb1b (diff)
parent157e0a0e8f68ab997b320a2d61c2d8ad20d5ce86 (diff)
downloadrust-a14b283022af5bdf7507f37e31638fc64ecca298.tar.gz
rust-a14b283022af5bdf7507f37e31638fc64ecca298.zip
Rollup merge of #87652 - npmccallum:naked_inline, r=Amanieu
Validate that naked functions are never inlined

Reject all uses of the inline attribute on naked functions.

https://github.com/rust-lang/rfcs/pull/2774
https://github.com/rust-lang/rfcs/pull/2972

cc `@joshtriplett` `@tmiasko` `@Amanieu`
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs3
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs12
-rw-r--r--src/test/ui/asm/naked-functions.rs43
-rw-r--r--src/test/ui/asm/naked-functions.stderr56
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