about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-01-22 15:32:54 +0100
committerGitHub <noreply@github.com>2022-01-22 15:32:54 +0100
commita8f64c04150f239e480aed6245273391d8bc3ea5 (patch)
treebc2ea97b109499a7ae3f54a36066cf4e5e833383
parent5fd9c059efaa76efeb2c85782a94aec343fd8bdc (diff)
parentbeeba4bcea8151cb43b2e5e45d083700cec4a26f (diff)
downloadrust-a8f64c04150f239e480aed6245273391d8bc3ea5.tar.gz
rust-a8f64c04150f239e480aed6245273391d8bc3ea5.zip
Rollup merge of #93153 - tmiasko:reject-unsupported-naked-functions, r=Amanieu
Reject unsupported naked functions

Transition unsupported naked functions future incompatibility lint into an error:

* Naked functions must contain a single inline assembly block. Introduced as future incompatibility lint in 1.50 #79653. Change into an error fixes a soundness issue described in #32489.

* Naked functions must not use any forms of inline attribute. Introduced as future incompatibility lint in 1.56 #87652.

Closes #32490.
Closes #32489.

r? ```@Amanieu``` ```@npmccallum``` ```@joshtriplett```
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs1
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0787.md28
-rw-r--r--compiler/rustc_lint/src/lib.rs5
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs47
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs92
-rw-r--r--src/test/codegen/naked-functions.rs40
-rw-r--r--src/test/codegen/naked-noinline.rs1
-rw-r--r--src/test/ui/asm/naked-functions.rs71
-rw-r--r--src/test/ui/asm/naked-functions.stderr181
9 files changed, 183 insertions, 283 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 79d9c55b547..d4b12d00f1f 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -486,6 +486,7 @@ E0783: include_str!("./error_codes/E0783.md"),
 E0784: include_str!("./error_codes/E0784.md"),
 E0785: include_str!("./error_codes/E0785.md"),
 E0786: include_str!("./error_codes/E0786.md"),
+E0787: include_str!("./error_codes/E0787.md"),
 ;
 //  E0006, // merged with E0005
 //  E0008, // cannot bind by-move into a pattern guard
diff --git a/compiler/rustc_error_codes/src/error_codes/E0787.md b/compiler/rustc_error_codes/src/error_codes/E0787.md
new file mode 100644
index 00000000000..cee50829270
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0787.md
@@ -0,0 +1,28 @@
+An unsupported naked function definition.
+
+Erroneous code example:
+
+```compile_fail,E0787
+#![feature(naked_functions)]
+
+#[naked]
+pub extern "C" fn f() -> u32 {
+    42
+}
+```
+
+The naked functions must be defined using a single inline assembly
+block.
+
+The execution must never fall through past the end of the assembly
+code so the block must use `noreturn` option. The asm block can also
+use `att_syntax` and `raw` options, but others options are not allowed.
+
+The asm block must not contain any operands other than `const` and
+`sym`.
+
+### Additional information
+
+For more information, please see [RFC 2972].
+
+[RFC 2972]: https://github.com/rust-lang/rfcs/blob/master/text/2972-constrained-naked.md
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 4aa8505c940..dde47c1e4c4 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -481,6 +481,11 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
          <https://github.com/rust-lang/rust/issues/59014> for more information",
     );
     store.register_removed("plugin_as_library", "plugins have been deprecated and retired");
+    store.register_removed(
+        "unsupported_naked_functions",
+        "converted into hard error, see RFC 2972 \
+         <https://github.com/rust-lang/rfcs/blob/master/text/2972-constrained-naked.md> 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 c2f6118227a..4096815c6a4 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -2760,52 +2760,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `unsupported_naked_functions` lint detects naked function
-    /// definitions that are unsupported but were previously accepted.
-    ///
-    /// ### Example
-    ///
-    /// ```rust
-    /// #![feature(naked_functions)]
-    ///
-    /// #[naked]
-    /// pub extern "C" fn f() -> u32 {
-    ///     42
-    /// }
-    /// ```
-    ///
-    /// {{produces}}
-    ///
-    /// ### Explanation
-    ///
-    /// The naked functions must be defined using a single inline assembly
-    /// block.
-    ///
-    /// The execution must never fall through past the end of the assembly
-    /// code so the block must use `noreturn` option. The asm block can also
-    /// use `att_syntax` option, but other options are not allowed.
-    ///
-    /// 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
-    /// the future.
-    ///
-    /// [future-incompatible]: ../index.md#future-incompatible-lints
-    pub UNSUPPORTED_NAKED_FUNCTIONS,
-    Warn,
-    "unsupported naked function definitions",
-    @future_incompatible = FutureIncompatibleInfo {
-        reference: "issue #32408 <https://github.com/rust-lang/rust/issues/32408>",
-    };
-}
-
-declare_lint! {
     /// The `ineffective_unstable_trait_impl` lint detects `#[unstable]` attributes which are not used.
     ///
     /// ### Example
@@ -3070,7 +3024,6 @@ declare_lint_pass! {
         UNINHABITED_STATIC,
         FUNCTION_ITEM_REFERENCES,
         USELESS_DEPRECATED,
-        UNSUPPORTED_NAKED_FUNCTIONS,
         MISSING_ABI,
         INVALID_DOC_ATTRIBUTES,
         SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index 0228196d1a1..00a93ccc9aa 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -1,6 +1,7 @@
 //! Checks validity of naked functions.
 
 use rustc_ast::{Attribute, InlineAsmOptions};
+use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{FnKind, Visitor};
@@ -8,7 +9,6 @@ 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;
 use rustc_target::spec::abi::Abi;
@@ -64,18 +64,16 @@ impl<'tcx> Visitor<'tcx> for CheckNakedFunctions<'tcx> {
             check_abi(self.tcx, hir_id, fn_header.abi, ident_span);
             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_asm(self.tcx, body, span);
+            check_inline(self.tcx, attrs);
         }
     }
 }
 
 /// Check that the function isn't inlined.
-fn check_inline(tcx: TyCtxt<'_>, hir_id: HirId, attrs: &[Attribute]) {
+fn check_inline(tcx: TyCtxt<'_>, 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();
-        });
+        tcx.sess.struct_span_err(attr.span, "naked functions cannot be inlined").emit();
     }
 }
 
@@ -146,31 +144,31 @@ impl<'tcx> Visitor<'tcx> for CheckParameters<'tcx> {
 }
 
 /// Checks that function body contains a single inline assembly block.
-fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, hir_id: HirId, body: &'tcx hir::Body<'tcx>, fn_span: Span) {
+fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, body: &'tcx hir::Body<'tcx>, fn_span: Span) {
     let mut this = CheckInlineAssembly { tcx, items: Vec::new() };
     this.visit_body(body);
     if let [(ItemKind::Asm, _)] = this.items[..] {
         // Ok.
     } else {
-        tcx.struct_span_lint_hir(UNSUPPORTED_NAKED_FUNCTIONS, hir_id, fn_span, |lint| {
-            let mut diag = lint.build("naked functions must contain a single asm block");
-            let mut has_asm = false;
-            for &(kind, span) in &this.items {
-                match kind {
-                    ItemKind::Asm if has_asm => {
-                        diag.span_label(
-                            span,
-                            "multiple asm blocks are unsupported in naked functions",
-                        );
-                    }
-                    ItemKind::Asm => has_asm = true,
-                    ItemKind::NonAsm => {
-                        diag.span_label(span, "non-asm is unsupported in naked functions");
-                    }
+        let mut diag = struct_span_err!(
+            tcx.sess,
+            fn_span,
+            E0787,
+            "naked functions must contain a single asm block"
+        );
+        let mut has_asm = false;
+        for &(kind, span) in &this.items {
+            match kind {
+                ItemKind::Asm if has_asm => {
+                    diag.span_label(span, "multiple asm blocks are unsupported in naked functions");
+                }
+                ItemKind::Asm => has_asm = true,
+                ItemKind::NonAsm => {
+                    diag.span_label(span, "non-asm is unsupported in naked functions");
                 }
             }
-            diag.emit();
-        });
+        }
+        diag.emit();
     }
 }
 
@@ -221,7 +219,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
 
             ExprKind::InlineAsm(ref asm) => {
                 self.items.push((ItemKind::Asm, span));
-                self.check_inline_asm(expr.hir_id, asm, span);
+                self.check_inline_asm(asm, span);
             }
 
             ExprKind::DropTemps(..) | ExprKind::Block(..) | ExprKind::Err => {
@@ -230,7 +228,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
         }
     }
 
-    fn check_inline_asm(&self, hir_id: HirId, asm: &'tcx hir::InlineAsm<'tcx>, span: Span) {
+    fn check_inline_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>, span: Span) {
         let unsupported_operands: Vec<Span> = asm
             .operands
             .iter()
@@ -243,18 +241,17 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
             })
             .collect();
         if !unsupported_operands.is_empty() {
-            self.tcx.struct_span_lint_hir(
-                UNSUPPORTED_NAKED_FUNCTIONS,
-                hir_id,
+            struct_span_err!(
+                self.tcx.sess,
                 unsupported_operands,
-                |lint| {
-                    lint.build("only `const` and `sym` operands are supported in naked functions")
-                        .emit();
-                },
-            );
+                E0787,
+                "only `const` and `sym` operands are supported in naked functions",
+            )
+            .emit();
         }
 
         let unsupported_options: Vec<&'static str> = [
+            (InlineAsmOptions::MAY_UNWIND, "`may_unwind`"),
             (InlineAsmOptions::NOMEM, "`nomem`"),
             (InlineAsmOptions::NOSTACK, "`nostack`"),
             (InlineAsmOptions::PRESERVES_FLAGS, "`preserves_flags`"),
@@ -266,19 +263,24 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
         .collect();
 
         if !unsupported_options.is_empty() {
-            self.tcx.struct_span_lint_hir(UNSUPPORTED_NAKED_FUNCTIONS, hir_id, span, |lint| {
-                lint.build(&format!(
-                    "asm options unsupported in naked functions: {}",
-                    unsupported_options.join(", ")
-                ))
-                .emit();
-            });
+            struct_span_err!(
+                self.tcx.sess,
+                span,
+                E0787,
+                "asm options unsupported in naked functions: {}",
+                unsupported_options.join(", ")
+            )
+            .emit();
         }
 
         if !asm.options.contains(InlineAsmOptions::NORETURN) {
-            self.tcx.struct_span_lint_hir(UNSUPPORTED_NAKED_FUNCTIONS, hir_id, span, |lint| {
-                lint.build("asm in naked functions must use `noreturn` option").emit();
-            });
+            struct_span_err!(
+                self.tcx.sess,
+                span,
+                E0787,
+                "asm in naked functions must use `noreturn` option"
+            )
+            .emit();
         }
     }
 }
diff --git a/src/test/codegen/naked-functions.rs b/src/test/codegen/naked-functions.rs
index c8cd6923282..51c7a0c615d 100644
--- a/src/test/codegen/naked-functions.rs
+++ b/src/test/codegen/naked-functions.rs
@@ -1,42 +1,32 @@
 // compile-flags: -C no-prepopulate-passes
+// needs-asm-support
+// only-x86_64
 
 #![crate_type = "lib"]
 #![feature(naked_functions)]
+use std::arch::asm;
 
 // CHECK: Function Attrs: naked
 // CHECK-NEXT: define{{.*}}void @naked_empty()
 #[no_mangle]
 #[naked]
-pub fn naked_empty() {
+pub unsafe extern "C" fn naked_empty() {
     // CHECK-NEXT: {{.+}}:
-    // CHECK-NEXT: ret void
+    // CHECK-NEXT: call void asm
+    // CHECK-NEXT: unreachable
+    asm!("ret",
+         options(noreturn));
 }
 
 // CHECK: Function Attrs: naked
+// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_args_and_return(i64 %a, i64 %b)
 #[no_mangle]
 #[naked]
-// CHECK-NEXT: define{{.*}}void @naked_with_args(i{{[0-9]+( %a)?}})
-pub fn naked_with_args(a: isize) {
+pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {
     // CHECK-NEXT: {{.+}}:
-    // CHECK: ret void
-}
-
-// CHECK: Function Attrs: naked
-// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_return()
-#[no_mangle]
-#[naked]
-pub fn naked_with_return() -> isize {
-    // CHECK-NEXT: {{.+}}:
-    // CHECK-NEXT: ret i{{[0-9]+}} 0
-    0
-}
-
-// CHECK: Function Attrs: naked
-// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+( %a)?}})
-#[no_mangle]
-#[naked]
-pub fn naked_with_args_and_return(a: isize) -> isize {
-    // CHECK-NEXT: {{.+}}:
-    // CHECK: ret i{{[0-9]+}} 0
-    0
+    // CHECK-NEXT: call void asm
+    // CHECK-NEXT: unreachable
+    asm!("lea rax, [rdi + rsi]",
+         "ret",
+         options(noreturn));
 }
diff --git a/src/test/codegen/naked-noinline.rs b/src/test/codegen/naked-noinline.rs
index e34ccf5c5fe..13bc139ecd0 100644
--- a/src/test/codegen/naked-noinline.rs
+++ b/src/test/codegen/naked-noinline.rs
@@ -7,7 +7,6 @@
 
 use std::arch::asm;
 
-#[inline(always)]
 #[naked]
 #[no_mangle]
 pub unsafe extern "C" fn f() {
diff --git a/src/test/ui/asm/naked-functions.rs b/src/test/ui/asm/naked-functions.rs
index 32431d9e7c6..5b4293972ea 100644
--- a/src/test/ui/asm/naked-functions.rs
+++ b/src/test/ui/asm/naked-functions.rs
@@ -5,7 +5,7 @@
 
 #![feature(naked_functions)]
 #![feature(or_patterns)]
-#![feature(asm_const, asm_sym)]
+#![feature(asm_const, asm_sym, asm_unwind)]
 #![crate_type = "lib"]
 
 use std::arch::asm;
@@ -32,8 +32,7 @@ pub unsafe extern "C" fn patterns(
 
 #[naked]
 pub unsafe extern "C" fn inc(a: u32) -> u32 {
-    //~^ WARN naked functions must contain a single asm block
-    //~| WARN this was previously accepted
+    //~^ ERROR naked functions must contain a single asm block
     a + 1
     //~^ ERROR referencing function parameters is not allowed in naked functions
 }
@@ -42,21 +41,18 @@ pub unsafe extern "C" fn inc(a: u32) -> u32 {
 pub unsafe extern "C" fn inc_asm(a: u32) -> u32 {
     asm!("/* {0} */", in(reg) a, options(noreturn));
     //~^ ERROR referencing function parameters is not allowed in naked functions
-    //~| WARN only `const` and `sym` operands are supported in naked functions
-    //~| WARN this was previously accepted
+    //~| ERROR only `const` and `sym` operands are supported in naked functions
 }
 
 #[naked]
 pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
-    //~^ WARN naked functions must contain a single asm block
-    //~| WARN this was previously accepted
+    //~^ ERROR naked functions must contain a single asm block
     (|| a + 1)()
 }
 
 #[naked]
 pub unsafe extern "C" fn unsupported_operands() {
-    //~^ WARN naked functions must contain a single asm block
-    //~| WARN this was previously accepted
+    //~^ ERROR naked functions must contain a single asm block
     let mut a = 0usize;
     let mut b = 0usize;
     let mut c = 0usize;
@@ -65,11 +61,9 @@ pub unsafe extern "C" fn unsupported_operands() {
     const F: usize = 0usize;
     static G: usize = 0usize;
     asm!("/* {0} {1} {2} {3} {4} {5} {6} */",
-         //~^ WARN asm in naked functions must use `noreturn` option
-         //~| WARN this was previously accepted
+         //~^ ERROR asm in naked functions must use `noreturn` option
          in(reg) a,
-         //~^ WARN only `const` and `sym` operands are supported in naked functions
-         //~| WARN this was previously accepted
+         //~^ ERROR only `const` and `sym` operands are supported in naked functions
          inlateout(reg) b,
          inout(reg) c,
          lateout(reg) d,
@@ -81,31 +75,25 @@ pub unsafe extern "C" fn unsupported_operands() {
 
 #[naked]
 pub extern "C" fn missing_assembly() {
-    //~^ WARN naked functions must contain a single asm block
-    //~| WARN this was previously accepted
+    //~^ ERROR naked functions must contain a single asm block
 }
 
 #[naked]
 pub extern "C" fn too_many_asm_blocks() {
-    //~^ WARN naked functions must contain a single asm block
-    //~| WARN this was previously accepted
+    //~^ ERROR naked functions must contain a single asm block
     asm!("");
-    //~^ WARN asm in naked functions must use `noreturn` option
-    //~| WARN this was previously accepted
+    //~^ ERROR asm in naked functions must use `noreturn` option
     asm!("");
-    //~^ WARN asm in naked functions must use `noreturn` option
-    //~| WARN this was previously accepted
+    //~^ ERROR asm in naked functions must use `noreturn` option
     asm!("");
-    //~^ WARN asm in naked functions must use `noreturn` option
-    //~| WARN this was previously accepted
+    //~^ ERROR asm in naked functions must use `noreturn` option
     asm!("", options(noreturn));
 }
 
 pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
     #[naked]
     pub extern "C" fn inner(y: usize) -> usize {
-        //~^ WARN naked functions must contain a single asm block
-        //~| WARN this was previously accepted
+        //~^ ERROR naked functions must contain a single asm block
         *&y
         //~^ ERROR referencing function parameters is not allowed in naked functions
     }
@@ -115,18 +103,21 @@ pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
 #[naked]
 unsafe extern "C" fn invalid_options() {
     asm!("", options(nomem, preserves_flags, noreturn));
-    //~^ WARN asm options unsupported in naked functions: `nomem`, `preserves_flags`
-    //~| WARN this was previously accepted
+    //~^ ERROR asm options unsupported in naked functions: `nomem`, `preserves_flags`
 }
 
 #[naked]
 unsafe extern "C" fn invalid_options_continued() {
     asm!("", options(readonly, nostack), options(pure));
     //~^ ERROR asm with the `pure` option must have at least one output
-    //~| WARN asm options unsupported in naked functions: `nostack`, `pure`, `readonly`
-    //~| WARN this was previously accepted
-    //~| WARN asm in naked functions must use `noreturn` option
-    //~| WARN this was previously accepted
+    //~| ERROR asm options unsupported in naked functions: `nostack`, `pure`, `readonly`
+    //~| ERROR asm in naked functions must use `noreturn` option
+}
+
+#[naked]
+unsafe extern "C" fn invalid_may_unwind() {
+    asm!("", options(noreturn, may_unwind));
+    //~^ ERROR asm options unsupported in naked functions: `may_unwind`
 }
 
 #[naked]
@@ -177,38 +168,32 @@ pub unsafe extern "C" fn inline_none() {
 
 #[naked]
 #[inline]
-//~^ WARN naked functions cannot be inlined
-//~| WARN this was previously accepted
+//~^ ERROR naked functions cannot be inlined
 pub unsafe extern "C" fn inline_hint() {
     asm!("", options(noreturn));
 }
 
 #[naked]
 #[inline(always)]
-//~^ WARN naked functions cannot be inlined
-//~| WARN this was previously accepted
+//~^ ERROR naked functions cannot be inlined
 pub unsafe extern "C" fn inline_always() {
     asm!("", options(noreturn));
 }
 
 #[naked]
 #[inline(never)]
-//~^ WARN naked functions cannot be inlined
-//~| WARN this was previously accepted
+//~^ ERROR naked functions cannot be inlined
 pub unsafe extern "C" fn inline_never() {
     asm!("", options(noreturn));
 }
 
 #[naked]
 #[inline]
-//~^ WARN naked functions cannot be inlined
-//~| WARN this was previously accepted
+//~^ ERROR naked functions cannot be inlined
 #[inline(always)]
-//~^ WARN naked functions cannot be inlined
-//~| WARN this was previously accepted
+//~^ ERROR naked functions cannot be inlined
 #[inline(never)]
-//~^ WARN naked functions cannot be inlined
-//~| WARN this was previously accepted
+//~^ ERROR naked functions cannot be inlined
 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 c2dfe443d60..c1dcc433db6 100644
--- a/src/test/ui/asm/naked-functions.stderr
+++ b/src/test/ui/asm/naked-functions.stderr
@@ -1,5 +1,5 @@
 error: asm with the `pure` option must have at least one output
-  --> $DIR/naked-functions.rs:124:14
+  --> $DIR/naked-functions.rs:111:14
    |
 LL |     asm!("", options(readonly, nostack), options(pure));
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^
@@ -29,66 +29,54 @@ LL |     P { x, y }: P,
    |     ^^^^^^^^^^
 
 error: referencing function parameters is not allowed in naked functions
-  --> $DIR/naked-functions.rs:37:5
+  --> $DIR/naked-functions.rs:36:5
    |
 LL |     a + 1
    |     ^
    |
    = help: follow the calling convention in asm block to use parameters
 
-warning: naked functions must contain a single asm block
+error[E0787]: naked functions must contain a single asm block
   --> $DIR/naked-functions.rs:34:1
    |
 LL | / pub unsafe extern "C" fn inc(a: u32) -> u32 {
 LL | |
-LL | |
 LL | |     a + 1
    | |     ----- non-asm is unsupported in naked functions
 LL | |
 LL | | }
    | |_^
-   |
-   = note: `#[warn(unsupported_naked_functions)]` on by default
-   = 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: referencing function parameters is not allowed in naked functions
-  --> $DIR/naked-functions.rs:43:31
+  --> $DIR/naked-functions.rs:42:31
    |
 LL |     asm!("/* {0} */", in(reg) a, options(noreturn));
    |                               ^
    |
    = help: follow the calling convention in asm block to use parameters
 
-warning: only `const` and `sym` operands are supported in naked functions
-  --> $DIR/naked-functions.rs:43:23
+error[E0787]: only `const` and `sym` operands are supported in naked functions
+  --> $DIR/naked-functions.rs:42:23
    |
 LL |     asm!("/* {0} */", in(reg) a, options(noreturn));
    |                       ^^^^^^^^^
-   |
-   = 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 must contain a single asm block
-  --> $DIR/naked-functions.rs:50:1
+error[E0787]: naked functions must contain a single asm block
+  --> $DIR/naked-functions.rs:48:1
    |
 LL | / pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
 LL | |
-LL | |
 LL | |     (|| a + 1)()
    | |     ------------ non-asm is unsupported in naked functions
 LL | | }
    | |_^
-   |
-   = 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: only `const` and `sym` operands are supported in naked functions
-  --> $DIR/naked-functions.rs:70:10
+error[E0787]: only `const` and `sym` operands are supported in naked functions
+  --> $DIR/naked-functions.rs:65:10
    |
 LL |          in(reg) a,
    |          ^^^^^^^^^
-...
+LL |
 LL |          inlateout(reg) b,
    |          ^^^^^^^^^^^^^^^^
 LL |          inout(reg) c,
@@ -97,31 +85,24 @@ LL |          lateout(reg) d,
    |          ^^^^^^^^^^^^^^
 LL |          out(reg) e,
    |          ^^^^^^^^^^
-   |
-   = 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: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:67:5
+error[E0787]: asm in naked functions must use `noreturn` option
+  --> $DIR/naked-functions.rs:63:5
    |
 LL | /     asm!("/* {0} {1} {2} {3} {4} {5} {6} */",
 LL | |
-LL | |
 LL | |          in(reg) a,
+LL | |
 ...  |
 LL | |          sym G,
 LL | |     );
    | |_____^
-   |
-   = 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 must contain a single asm block
-  --> $DIR/naked-functions.rs:57:1
+error[E0787]: naked functions must contain a single asm block
+  --> $DIR/naked-functions.rs:54:1
    |
 LL | / pub unsafe extern "C" fn unsupported_operands() {
 LL | |
-LL | |
 LL | |     let mut a = 0usize;
    | |     ------------------- non-asm is unsupported in naked functions
 LL | |     let mut b = 0usize;
@@ -136,123 +117,96 @@ LL | |     let mut e = 0usize;
 LL | |     );
 LL | | }
    | |_^
-   |
-   = 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 must contain a single asm block
-  --> $DIR/naked-functions.rs:83:1
+error[E0787]: naked functions must contain a single asm block
+  --> $DIR/naked-functions.rs:77:1
    |
 LL | / pub extern "C" fn missing_assembly() {
 LL | |
-LL | |
 LL | | }
    | |_^
-   |
-   = 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: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:92:5
+error[E0787]: asm in naked functions must use `noreturn` option
+  --> $DIR/naked-functions.rs:84:5
    |
 LL |     asm!("");
    |     ^^^^^^^^
-   |
-   = 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: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:95:5
+error[E0787]: asm in naked functions must use `noreturn` option
+  --> $DIR/naked-functions.rs:86:5
    |
 LL |     asm!("");
    |     ^^^^^^^^
-   |
-   = 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: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:98:5
+error[E0787]: asm in naked functions must use `noreturn` option
+  --> $DIR/naked-functions.rs:88:5
    |
 LL |     asm!("");
    |     ^^^^^^^^
-   |
-   = 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 must contain a single asm block
-  --> $DIR/naked-functions.rs:89:1
+error[E0787]: naked functions must contain a single asm block
+  --> $DIR/naked-functions.rs:82:1
    |
 LL | / pub extern "C" fn too_many_asm_blocks() {
 LL | |
-LL | |
 LL | |     asm!("");
-...  |
+LL | |
 LL | |     asm!("");
    | |     -------- multiple asm blocks are unsupported in naked functions
-...  |
+LL | |
 LL | |     asm!("");
    | |     -------- multiple asm blocks are unsupported in naked functions
-...  |
+LL | |
 LL | |     asm!("", options(noreturn));
    | |     --------------------------- multiple asm blocks are unsupported in naked functions
 LL | | }
    | |_^
-   |
-   = 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: referencing function parameters is not allowed in naked functions
-  --> $DIR/naked-functions.rs:109:11
+  --> $DIR/naked-functions.rs:97:11
    |
 LL |         *&y
    |           ^
    |
    = help: follow the calling convention in asm block to use parameters
 
-warning: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:106:5
+error[E0787]: naked functions must contain a single asm block
+  --> $DIR/naked-functions.rs:95:5
    |
 LL | /     pub extern "C" fn inner(y: usize) -> usize {
 LL | |
-LL | |
 LL | |         *&y
    | |         --- non-asm is unsupported in naked functions
 LL | |
 LL | |     }
    | |_____^
-   |
-   = 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: asm options unsupported in naked functions: `nomem`, `preserves_flags`
-  --> $DIR/naked-functions.rs:117:5
+error[E0787]: asm options unsupported in naked functions: `nomem`, `preserves_flags`
+  --> $DIR/naked-functions.rs:105:5
    |
 LL |     asm!("", options(nomem, preserves_flags, noreturn));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = 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: asm options unsupported in naked functions: `nostack`, `pure`, `readonly`
-  --> $DIR/naked-functions.rs:124:5
+error[E0787]: asm options unsupported in naked functions: `nostack`, `pure`, `readonly`
+  --> $DIR/naked-functions.rs:111:5
    |
 LL |     asm!("", options(readonly, nostack), options(pure));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = 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: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:124:5
+error[E0787]: asm in naked functions must use `noreturn` option
+  --> $DIR/naked-functions.rs:111:5
    |
 LL |     asm!("", options(readonly, nostack), options(pure));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0787]: asm options unsupported in naked functions: `may_unwind`
+  --> $DIR/naked-functions.rs:119:5
    |
-   = 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>
+LL |     asm!("", options(noreturn, may_unwind));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: Rust ABI is unsupported in naked functions
-  --> $DIR/naked-functions.rs:133:15
+  --> $DIR/naked-functions.rs:124:15
    |
 LL | pub unsafe fn default_abi() {
    |               ^^^^^^^^^^^
@@ -260,64 +214,47 @@ 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:139:15
+  --> $DIR/naked-functions.rs:130:15
    |
 LL | pub unsafe fn rust_abi() {
    |               ^^^^^^^^
 
-warning: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:179:1
+error: naked functions cannot be inlined
+  --> $DIR/naked-functions.rs:170: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:187:1
+error: naked functions cannot be inlined
+  --> $DIR/naked-functions.rs:177: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:195:1
+error: naked functions cannot be inlined
+  --> $DIR/naked-functions.rs:184: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:203:1
+error: naked functions cannot be inlined
+  --> $DIR/naked-functions.rs:191: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:206:1
+error: naked functions cannot be inlined
+  --> $DIR/naked-functions.rs:193: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:209:1
+error: naked functions cannot be inlined
+  --> $DIR/naked-functions.rs:195: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; 23 warnings emitted
+error: aborting due to 30 previous errors; 2 warnings emitted
 
+For more information about this error, try `rustc --explain E0787`.