about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFolkert de Vries <folkert@folkertdev.nl>2024-09-05 13:45:26 +0200
committerFolkert de Vries <folkert@folkertdev.nl>2024-10-06 18:12:25 +0200
commit562ec5a6fb469a360b72aa8ba0ce149598cc7975 (patch)
treeef26a0c513a413e9a7994389cdfd5796e5a69b68
parent1a9c1cbf367fb2b6f04a0a81d7fae56485e29e7f (diff)
downloadrust-562ec5a6fb469a360b72aa8ba0ce149598cc7975.tar.gz
rust-562ec5a6fb469a360b72aa8ba0ce149598cc7975.zip
disallow `asm!` in `#[naked]` functions
also disallow the `noreturn` option, and infer `naked_asm!` as `!`
-rw-r--r--compiler/rustc_ast/src/ast.rs20
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs62
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0787.md5
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs6
-rw-r--r--compiler/rustc_passes/messages.ftl12
-rw-r--r--compiler/rustc_passes/src/errors.rs8
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs47
-rw-r--r--library/core/src/arch.rs14
-rw-r--r--src/tools/rustfmt/src/parse/macros/asm.rs4
-rw-r--r--tests/codegen/naked-fn/aligned.rs4
-rw-r--r--tests/codegen/naked-fn/naked-functions.rs4
-rw-r--r--tests/codegen/naked-fn/naked-nocoverage.rs4
-rw-r--r--tests/codegen/naked-fn/naked-noinline.rs4
-rw-r--r--tests/ui/asm/naked-functions-ffi.rs2
-rw-r--r--tests/ui/asm/naked-functions-inline.rs2
-rw-r--r--tests/ui/asm/naked-functions-instruction-set.rs4
-rw-r--r--tests/ui/asm/naked-functions-testattrs.rs8
-rw-r--r--tests/ui/asm/naked-functions-unused.rs10
-rw-r--r--tests/ui/asm/naked-functions.rs68
-rw-r--r--tests/ui/asm/naked-functions.stderr156
-rw-r--r--tests/ui/asm/naked-invalid-attr.rs13
-rw-r--r--tests/ui/asm/naked-invalid-attr.stderr6
-rw-r--r--tests/ui/asm/naked-with-invalid-repr-attr.rs12
-rw-r--r--tests/ui/asm/naked-with-invalid-repr-attr.stderr12
-rw-r--r--tests/ui/asm/named-asm-labels.rs10
-rw-r--r--tests/ui/asm/named-asm-labels.stderr18
-rw-r--r--tests/ui/feature-gates/feature-gate-naked_functions.rs4
27 files changed, 222 insertions, 297 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 37f429cce44..cb715213176 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2278,7 +2278,7 @@ impl InlineAsmOptions {
     pub const COUNT: usize = Self::all().bits().count_ones() as usize;
 
     pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
-    pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW).union(Self::NORETURN);
+    pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
 
     pub fn human_readable_names(&self) -> Vec<&'static str> {
         let mut options = vec![];
@@ -2434,6 +2434,24 @@ pub enum AsmMacro {
     NakedAsm,
 }
 
+impl AsmMacro {
+    pub const fn macro_name(&self) -> &'static str {
+        match self {
+            AsmMacro::Asm => "asm",
+            AsmMacro::GlobalAsm => "global_asm",
+            AsmMacro::NakedAsm => "naked_asm",
+        }
+    }
+
+    pub const fn is_supported_option(&self, option: InlineAsmOptions) -> bool {
+        match self {
+            AsmMacro::Asm => true,
+            AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
+            AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
+        }
+    }
+}
+
 /// Inline assembly.
 ///
 /// E.g., `asm!("NOP");`.
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 2019c42e296..515ac17f70a 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -60,35 +60,6 @@ fn eat_operand_keyword<'a>(
     }
 }
 
-// Public for rustfmt consumption.
-#[derive(Copy, Clone)]
-pub enum AsmMacro {
-    /// The `asm!` macro
-    Asm,
-    /// The `global_asm!` macro
-    GlobalAsm,
-    /// The `naked_asm!` macro
-    NakedAsm,
-}
-
-impl AsmMacro {
-    const fn macro_name(&self) -> &'static str {
-        match self {
-            AsmMacro::Asm => "asm",
-            AsmMacro::GlobalAsm => "global_asm",
-            AsmMacro::NakedAsm => "naked_asm",
-        }
-    }
-
-    const fn is_supported_option(&self, option: ast::InlineAsmOptions) -> bool {
-        match self {
-            AsmMacro::Asm => true,
-            AsmMacro::GlobalAsm => ast::InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
-            AsmMacro::NakedAsm => ast::InlineAsmOptions::NAKED_OPTIONS.contains(option),
-        }
-    }
-}
-
 fn parse_args<'a>(
     ecx: &ExtCtxt<'a>,
     sp: Span,
@@ -529,7 +500,7 @@ fn parse_reg<'a>(
 
 fn expand_preparsed_asm(
     ecx: &mut ExtCtxt<'_>,
-    asm_macro: ast::AsmMacro,
+    asm_macro: AsmMacro,
     args: AsmArgs,
 ) -> ExpandResult<Result<ast::InlineAsm, ErrorGuaranteed>, ()> {
     let mut template = vec![];
@@ -872,7 +843,7 @@ pub(super) fn expand_naked_asm<'cx>(
     sp: Span,
     tts: TokenStream,
 ) -> MacroExpanderResult<'cx> {
-    ExpandResult::Ready(match parse_args(ecx, sp, tts, false) {
+    ExpandResult::Ready(match parse_args(ecx, sp, tts, AsmMacro::NakedAsm) {
         Ok(args) => {
             let ExpandResult::Ready(mac) = expand_preparsed_asm(ecx, AsmMacro::NakedAsm, args)
             else {
@@ -940,32 +911,3 @@ pub(super) fn expand_global_asm<'cx>(
         }
     })
 }
-
-pub(super) fn expand_naked_asm<'cx>(
-    ecx: &'cx mut ExtCtxt<'_>,
-    sp: Span,
-    tts: TokenStream,
-) -> MacroExpanderResult<'cx> {
-    ExpandResult::Ready(match parse_args(ecx, sp, tts, AsmMacro::NakedAsm) {
-        Ok(args) => {
-            let ExpandResult::Ready(mac) = expand_preparsed_asm(ecx, args) else {
-                return ExpandResult::Retry(());
-            };
-            let expr = match mac {
-                Ok(inline_asm) => P(ast::Expr {
-                    id: ast::DUMMY_NODE_ID,
-                    kind: ast::ExprKind::InlineAsm(P(inline_asm)),
-                    span: sp,
-                    attrs: ast::AttrVec::new(),
-                    tokens: None,
-                }),
-                Err(guar) => DummyResult::raw_expr(sp, Some(guar)),
-            };
-            MacEager::expr(expr)
-        }
-        Err(err) => {
-            let guar = err.emit();
-            DummyResult::any(sp, guar)
-        }
-    })
-}
diff --git a/compiler/rustc_error_codes/src/error_codes/E0787.md b/compiler/rustc_error_codes/src/error_codes/E0787.md
index cee50829270..f5c5faa066b 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0787.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0787.md
@@ -11,11 +11,10 @@ pub extern "C" fn f() -> u32 {
 }
 ```
 
-The naked functions must be defined using a single inline assembly
-block.
+The naked function must be defined using a single `naked_asm!` 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
+code, so it must either return or diverge. 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
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 2d718295374..5c2f39f879c 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -3507,7 +3507,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     fn check_expr_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>) -> Ty<'tcx> {
-        let mut diverge = asm.options.contains(ast::InlineAsmOptions::NORETURN);
+        let mut diverge = match asm.asm_macro {
+            rustc_ast::AsmMacro::Asm => asm.options.contains(ast::InlineAsmOptions::NORETURN),
+            rustc_ast::AsmMacro::GlobalAsm => true,
+            rustc_ast::AsmMacro::NakedAsm => true,
+        };
 
         for (op, _op_sp) in asm.operands {
             match op {
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index f2682acf8aa..1b1d1b1fb72 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -488,9 +488,9 @@ passes_naked_asm_outside_naked_fn =
     the `naked_asm!` macro can only be used in functions marked with `#[naked]`
 
 passes_naked_functions_asm_block =
-    naked functions must contain a single asm block
-    .label_multiple_asm = multiple asm blocks are unsupported in naked functions
-    .label_non_asm = non-asm is unsupported in naked functions
+    naked functions must contain a single `naked_asm!` invocation
+    .label_multiple_asm = multiple `naked_asm!` invocations are not allowed in naked functions
+    .label_non_asm = not allowed in naked functions
 
 passes_naked_functions_asm_options =
     asm options unsupported in naked functions: {$unsupported_options}
@@ -500,9 +500,9 @@ passes_naked_functions_incompatible_attribute =
     .label = the `{$attr}` attribute is incompatible with `#[naked]`
     .naked_attribute = function marked with `#[naked]` here
 
-passes_naked_functions_must_use_noreturn =
-    asm in naked functions must use `noreturn` option
-    .suggestion = consider specifying that the asm block is responsible for returning from the function
+passes_naked_functions_must_naked_asm =
+    the `asm!` macro is not allowed in naked functions
+    .suggestion = consider using the `naked_asm!` macro instead
 
 passes_naked_functions_operands =
     only `const` and `sym` operands are supported in naked functions
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 29a087bf759..c46768ace53 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1202,12 +1202,12 @@ pub(crate) struct NakedFunctionsAsmOptions {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_naked_functions_must_use_noreturn, code = E0787)]
-pub(crate) struct NakedFunctionsMustUseNoreturn {
+#[diag(passes_naked_functions_must_naked_asm, code = E0787)]
+pub(crate) struct NakedFunctionsMustNakedAsm {
     #[primary_span]
     pub span: Span,
-    #[suggestion(code = ", options(noreturn)", applicability = "machine-applicable")]
-    pub last_span: Span,
+    #[suggestion(code = "naked_asm!", applicability = "machine-applicable")]
+    pub macro_span: Span,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index 8d3f7e0231f..6046c728430 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -10,13 +10,13 @@ use rustc_middle::hir::nested_filter::OnlyBodies;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::lint::builtin::UNDEFINED_NAKED_FUNCTION_ABI;
-use rustc_span::Span;
 use rustc_span::symbol::sym;
+use rustc_span::{BytePos, Span};
 use rustc_target::spec::abi::Abi;
 
 use crate::errors::{
     NakedAsmOutsideNakedFn, NakedFunctionsAsmBlock, NakedFunctionsAsmOptions,
-    NakedFunctionsMustUseNoreturn, NakedFunctionsOperands, NoPatterns, ParamsNotAllowed,
+    NakedFunctionsMustNakedAsm, NakedFunctionsOperands, NoPatterns, ParamsNotAllowed,
     UndefinedNakedFunctionAbi,
 };
 
@@ -121,21 +121,29 @@ impl<'tcx> Visitor<'tcx> for CheckParameters<'tcx> {
 fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir::Body<'tcx>) {
     let mut this = CheckInlineAssembly { tcx, items: Vec::new() };
     this.visit_body(body);
-    if let [(ItemKind::Asm | ItemKind::Err, _)] = this.items[..] {
+    if let [(ItemKind::NakedAsm | ItemKind::Err, _)] = this.items[..] {
         // Ok.
     } else {
         let mut must_show_error = false;
-        let mut has_asm = false;
+        let mut has_naked_asm = false;
         let mut has_err = false;
         let mut multiple_asms = vec![];
         let mut non_asms = vec![];
         for &(kind, span) in &this.items {
             match kind {
-                ItemKind::Asm if has_asm => {
+                ItemKind::NakedAsm if has_naked_asm => {
                     must_show_error = true;
                     multiple_asms.push(span);
                 }
-                ItemKind::Asm => has_asm = true,
+                ItemKind::NakedAsm => has_naked_asm = true,
+                ItemKind::InlineAsm => {
+                    has_err = true;
+
+                    // the span that contains the `asm!` call,
+                    // so tooling can replace it with `naked_asm!`
+                    let macro_span = span.with_hi(span.lo() + BytePos("asm!".len() as u32));
+                    tcx.dcx().emit_err(NakedFunctionsMustNakedAsm { span, macro_span });
+                }
                 ItemKind::NonAsm => {
                     must_show_error = true;
                     non_asms.push(span);
@@ -164,7 +172,8 @@ struct CheckInlineAssembly<'tcx> {
 
 #[derive(Copy, Clone)]
 enum ItemKind {
-    Asm,
+    NakedAsm,
+    InlineAsm,
     NonAsm,
     Err,
 }
@@ -205,8 +214,18 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
             }
 
             ExprKind::InlineAsm(asm) => {
-                self.items.push((ItemKind::Asm, span));
-                self.check_inline_asm(asm, span);
+                match asm.asm_macro {
+                    rustc_ast::AsmMacro::Asm => {
+                        self.items.push((ItemKind::InlineAsm, span));
+                    }
+                    rustc_ast::AsmMacro::NakedAsm => {
+                        self.items.push((ItemKind::NakedAsm, span));
+                        self.check_inline_asm(asm, span);
+                    }
+                    rustc_ast::AsmMacro::GlobalAsm => {
+                        // not allowed in this position
+                    }
+                }
             }
 
             ExprKind::DropTemps(..) | ExprKind::Block(..) => {
@@ -250,16 +269,6 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
                     .join(", "),
             });
         }
-
-        if !asm.options.contains(InlineAsmOptions::NORETURN) {
-            let last_span = asm
-                .operands
-                .last()
-                .map_or_else(|| asm.template_strs.last().unwrap().2, |op| op.1)
-                .shrink_to_hi();
-
-            self.tcx.dcx().emit_err(NakedFunctionsMustUseNoreturn { span, last_span });
-        }
     }
 }
 
diff --git a/library/core/src/arch.rs b/library/core/src/arch.rs
index f1a0739128c..4945c045bc6 100644
--- a/library/core/src/arch.rs
+++ b/library/core/src/arch.rs
@@ -77,17 +77,3 @@ pub macro naked_asm("assembly template", $(operands,)* $(options($(option),*))?)
 pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) {
     /* compiler built-in */
 }
-
-/// Inline assembly used in combination with `#[naked]` functions.
-///
-/// Refer to [Rust By Example] for a usage guide and the [reference] for
-/// detailed information about the syntax and available options.
-///
-/// [Rust By Example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
-/// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html
-#[unstable(feature = "naked_functions", issue = "90957")]
-#[rustc_builtin_macro]
-#[cfg(not(bootstrap))]
-pub macro naked_asm("assembly template", $(operands,)* $(options($(option),*))?) {
-    /* compiler built-in */
-}
diff --git a/src/tools/rustfmt/src/parse/macros/asm.rs b/src/tools/rustfmt/src/parse/macros/asm.rs
index 5d30171e295..0c37d12490e 100644
--- a/src/tools/rustfmt/src/parse/macros/asm.rs
+++ b/src/tools/rustfmt/src/parse/macros/asm.rs
@@ -1,5 +1,5 @@
 use rustc_ast::ast;
-use rustc_builtin_macros::asm::{parse_asm_args, AsmArgs, AsmMacro};
+use rustc_builtin_macros::asm::{parse_asm_args, AsmArgs};
 
 use crate::rewrite::RewriteContext;
 
@@ -7,5 +7,5 @@ use crate::rewrite::RewriteContext;
 pub(crate) fn parse_asm(context: &RewriteContext<'_>, mac: &ast::MacCall) -> Option<AsmArgs> {
     let ts = mac.args.tokens.clone();
     let mut parser = super::build_parser(context, ts);
-    parse_asm_args(&mut parser, mac.span(), AsmMacro::Asm).ok()
+    parse_asm_args(&mut parser, mac.span(), ast::AsmMacro::Asm).ok()
 }
diff --git a/tests/codegen/naked-fn/aligned.rs b/tests/codegen/naked-fn/aligned.rs
index d5faac44836..3bbd67981e5 100644
--- a/tests/codegen/naked-fn/aligned.rs
+++ b/tests/codegen/naked-fn/aligned.rs
@@ -4,7 +4,7 @@
 
 #![crate_type = "lib"]
 #![feature(naked_functions, fn_align)]
-use std::arch::asm;
+use std::arch::naked_asm;
 
 // CHECK: Function Attrs: naked
 // CHECK-NEXT: define{{.*}}void @naked_empty()
@@ -16,5 +16,5 @@ pub unsafe extern "C" fn naked_empty() {
     // CHECK-NEXT: start:
     // CHECK-NEXT: call void asm
     // CHECK-NEXT: unreachable
-    asm!("ret", options(noreturn));
+    naked_asm!("ret");
 }
diff --git a/tests/codegen/naked-fn/naked-functions.rs b/tests/codegen/naked-fn/naked-functions.rs
index 2b2625429f8..3f7447af599 100644
--- a/tests/codegen/naked-fn/naked-functions.rs
+++ b/tests/codegen/naked-fn/naked-functions.rs
@@ -14,7 +14,7 @@ pub unsafe extern "C" fn naked_empty() {
     // CHECK-NEXT: {{.+}}:
     // CHECK-NEXT: call void asm
     // CHECK-NEXT: unreachable
-    naked_asm!("ret", options(noreturn));
+    naked_asm!("ret");
 }
 
 // CHECK: Function Attrs: naked
@@ -25,5 +25,5 @@ pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize
     // CHECK-NEXT: {{.+}}:
     // CHECK-NEXT: call void asm
     // CHECK-NEXT: unreachable
-    naked_asm!("lea rax, [rdi + rsi]", "ret", options(noreturn));
+    naked_asm!("lea rax, [rdi + rsi]", "ret");
 }
diff --git a/tests/codegen/naked-fn/naked-nocoverage.rs b/tests/codegen/naked-fn/naked-nocoverage.rs
index d73c5b7fd26..f63661bcd3a 100644
--- a/tests/codegen/naked-fn/naked-nocoverage.rs
+++ b/tests/codegen/naked-fn/naked-nocoverage.rs
@@ -6,7 +6,7 @@
 //@ compile-flags: -Cinstrument-coverage
 #![crate_type = "lib"]
 #![feature(naked_functions)]
-use std::arch::asm;
+use std::arch::naked_asm;
 
 #[naked]
 #[no_mangle]
@@ -15,5 +15,5 @@ pub unsafe extern "C" fn f() {
     // CHECK-NEXT:  start:
     // CHECK-NEXT:    call void asm
     // CHECK-NEXT:    unreachable
-    asm!("", options(noreturn));
+    naked_asm!("");
 }
diff --git a/tests/codegen/naked-fn/naked-noinline.rs b/tests/codegen/naked-fn/naked-noinline.rs
index c1e8f368249..6ea36d96783 100644
--- a/tests/codegen/naked-fn/naked-noinline.rs
+++ b/tests/codegen/naked-fn/naked-noinline.rs
@@ -5,7 +5,7 @@
 #![crate_type = "lib"]
 #![feature(naked_functions)]
 
-use std::arch::asm;
+use std::arch::naked_asm;
 
 #[naked]
 #[no_mangle]
@@ -15,7 +15,7 @@ pub unsafe extern "C" fn f() {
     // CHECK:       define {{(dso_local )?}}void @f() unnamed_addr [[ATTR:#[0-9]+]]
     // CHECK-NEXT:  start:
     // CHECK-NEXT:    call void asm
-    asm!("", options(noreturn));
+    naked_asm!("");
 }
 
 #[no_mangle]
diff --git a/tests/ui/asm/naked-functions-ffi.rs b/tests/ui/asm/naked-functions-ffi.rs
index 6b32290905d..b78d1e6a0d1 100644
--- a/tests/ui/asm/naked-functions-ffi.rs
+++ b/tests/ui/asm/naked-functions-ffi.rs
@@ -10,6 +10,6 @@ pub extern "C" fn naked(p: char) -> u128 {
     //~^ WARN uses type `char`
     //~| WARN uses type `u128`
     unsafe {
-        naked_asm!("", options(noreturn));
+        naked_asm!("");
     }
 }
diff --git a/tests/ui/asm/naked-functions-inline.rs b/tests/ui/asm/naked-functions-inline.rs
index a4df38e3347..74049e8ecbc 100644
--- a/tests/ui/asm/naked-functions-inline.rs
+++ b/tests/ui/asm/naked-functions-inline.rs
@@ -19,7 +19,7 @@ pub unsafe extern "C" fn inline_hint() {
 #[naked]
 #[inline(always)]
 //~^ ERROR [E0736]
-<<<<<<< HEAD
+pub unsafe extern "C" fn inline_always() {
     naked_asm!("");
 }
 
diff --git a/tests/ui/asm/naked-functions-instruction-set.rs b/tests/ui/asm/naked-functions-instruction-set.rs
index 6c6dcdf0087..37c7b52c191 100644
--- a/tests/ui/asm/naked-functions-instruction-set.rs
+++ b/tests/ui/asm/naked-functions-instruction-set.rs
@@ -19,12 +19,12 @@ trait Sized {}
 #[naked]
 #[instruction_set(arm::t32)]
 unsafe extern "C" fn test_thumb() {
-    naked_asm!("bx lr", options(noreturn));
+    naked_asm!("bx lr");
 }
 
 #[no_mangle]
 #[naked]
 #[instruction_set(arm::t32)]
 unsafe extern "C" fn test_arm() {
-    naked_asm!("bx lr", options(noreturn));
+    naked_asm!("bx lr");
 }
diff --git a/tests/ui/asm/naked-functions-testattrs.rs b/tests/ui/asm/naked-functions-testattrs.rs
index 2532e6e86d6..7e373270e9f 100644
--- a/tests/ui/asm/naked-functions-testattrs.rs
+++ b/tests/ui/asm/naked-functions-testattrs.rs
@@ -12,7 +12,7 @@ use std::arch::naked_asm;
 #[naked]
 //~^ ERROR [E0736]
 fn test_naked() {
-    unsafe { naked_asm!("", options(noreturn)) };
+    unsafe { naked_asm!("") };
 }
 
 #[should_panic]
@@ -20,7 +20,7 @@ fn test_naked() {
 #[naked]
 //~^ ERROR [E0736]
 fn test_naked_should_panic() {
-    unsafe { naked_asm!("", options(noreturn)) };
+    unsafe { naked_asm!("") };
 }
 
 #[ignore]
@@ -28,12 +28,12 @@ fn test_naked_should_panic() {
 #[naked]
 //~^ ERROR [E0736]
 fn test_naked_ignore() {
-    unsafe { naked_asm!("", options(noreturn)) };
+    unsafe { naked_asm!("") };
 }
 
 #[bench]
 #[naked]
 //~^ ERROR [E0736]
 fn bench_naked() {
-    unsafe { naked_asm!("", options(noreturn)) };
+    unsafe { naked_asm!("") };
 }
diff --git a/tests/ui/asm/naked-functions-unused.rs b/tests/ui/asm/naked-functions-unused.rs
index 6d3cc0afed8..c27037819a4 100644
--- a/tests/ui/asm/naked-functions-unused.rs
+++ b/tests/ui/asm/naked-functions-unused.rs
@@ -67,7 +67,7 @@ pub mod naked {
     #[naked]
     pub extern "C" fn function(a: usize, b: usize) -> usize {
         unsafe {
-            naked_asm!("", options(noreturn));
+            naked_asm!("");
         }
     }
 
@@ -77,14 +77,14 @@ pub mod naked {
         #[naked]
         pub extern "C" fn associated(a: usize, b: usize) -> usize {
             unsafe {
-                naked_asm!("", options(noreturn));
+                naked_asm!("");
             }
         }
 
         #[naked]
         pub extern "C" fn method(&self, a: usize, b: usize) -> usize {
             unsafe {
-                naked_asm!("", options(noreturn));
+                naked_asm!("");
             }
         }
     }
@@ -93,14 +93,14 @@ pub mod naked {
         #[naked]
         extern "C" fn trait_associated(a: usize, b: usize) -> usize {
             unsafe {
-                naked_asm!("", options(noreturn));
+                naked_asm!("");
             }
         }
 
         #[naked]
         extern "C" fn trait_method(&self, a: usize, b: usize) -> usize {
             unsafe {
-                naked_asm!("", options(noreturn));
+                naked_asm!("");
             }
         }
     }
diff --git a/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs
index 86c89ea1262..5c58f1498cc 100644
--- a/tests/ui/asm/naked-functions.rs
+++ b/tests/ui/asm/naked-functions.rs
@@ -6,7 +6,13 @@
 #![feature(asm_unwind, linkage)]
 #![crate_type = "lib"]
 
-use std::arch::naked_asm;
+use std::arch::{asm, naked_asm};
+
+#[naked]
+pub unsafe extern "C" fn inline_asm_macro() {
+    asm!("", options(raw));
+    //~^ERROR the `asm!` macro is not allowed in naked functions
+}
 
 #[repr(C)]
 pub struct P {
@@ -25,12 +31,12 @@ pub unsafe extern "C" fn patterns(
     P { x, y }: P,
     //~^ ERROR patterns not allowed in naked function parameters
 ) {
-    naked_asm!("", options(noreturn))
+    naked_asm!("")
 }
 
 #[naked]
 pub unsafe extern "C" fn inc(a: u32) -> u32 {
-    //~^ ERROR naked functions must contain a single asm block
+    //~^ ERROR naked functions must contain a single `naked_asm!` invocation
     a + 1
     //~^ ERROR referencing function parameters is not allowed in naked functions
 }
@@ -38,19 +44,19 @@ pub unsafe extern "C" fn inc(a: u32) -> u32 {
 #[naked]
 #[allow(asm_sub_register)]
 pub unsafe extern "C" fn inc_asm(a: u32) -> u32 {
-    naked_asm!("/* {0} */", in(reg) a, options(noreturn))
+    naked_asm!("/* {0} */", in(reg) a)
     //~^ ERROR the `in` operand cannot be used with `naked_asm!`
 }
 
 #[naked]
 pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
-    //~^ ERROR naked functions must contain a single asm block
+    //~^ ERROR naked functions must contain a single `naked_asm!` invocation
     (|| a + 1)()
 }
 
 #[naked]
 pub unsafe extern "C" fn unsupported_operands() {
-    //~^ ERROR naked functions must contain a single asm block
+    //~^ ERROR naked functions must contain a single `naked_asm!` invocation
     let mut a = 0usize;
     let mut b = 0usize;
     let mut c = 0usize;
@@ -72,27 +78,23 @@ pub unsafe extern "C" fn unsupported_operands() {
 
 #[naked]
 pub extern "C" fn missing_assembly() {
-    //~^ ERROR naked functions must contain a single asm block
+    //~^ ERROR naked functions must contain a single `naked_asm!` invocation
 }
 
 #[naked]
 pub extern "C" fn too_many_asm_blocks() {
-    //~^ ERROR naked functions must contain a single asm block
+    //~^ ERROR naked functions must contain a single `naked_asm!` invocation
     unsafe {
-        naked_asm!("");
-        //~^ ERROR asm in naked functions must use `noreturn` option
-        naked_asm!("");
-        //~^ ERROR asm in naked functions must use `noreturn` option
-        naked_asm!("");
-        //~^ ERROR asm in naked functions must use `noreturn` option
         naked_asm!("", options(noreturn));
+        //~^ ERROR the `noreturn` option cannot be used with `naked_asm!`
+        naked_asm!("");
     }
 }
 
 pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
     #[naked]
     pub extern "C" fn inner(y: usize) -> usize {
-        //~^ ERROR naked functions must contain a single asm block
+        //~^ ERROR naked functions must contain a single `naked_asm!` invocation
         *&y
         //~^ ERROR referencing function parameters is not allowed in naked functions
     }
@@ -101,7 +103,7 @@ pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
 
 #[naked]
 unsafe extern "C" fn invalid_options() {
-    naked_asm!("", options(nomem, preserves_flags, noreturn));
+    naked_asm!("", options(nomem, preserves_flags));
     //~^ ERROR the `nomem` option cannot be used with `naked_asm!`
     //~| ERROR the `preserves_flags` option cannot be used with `naked_asm!`
 }
@@ -112,31 +114,30 @@ unsafe extern "C" fn invalid_options_continued() {
     //~^ ERROR the `readonly` option cannot be used with `naked_asm!`
     //~| ERROR the `nostack` option cannot be used with `naked_asm!`
     //~| ERROR the `pure` option cannot be used with `naked_asm!`
-    //~| ERROR asm in naked functions must use `noreturn` option
 }
 
 #[naked]
 unsafe extern "C" fn invalid_may_unwind() {
-    naked_asm!("", options(noreturn, may_unwind));
+    naked_asm!("", options(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!("", options(noreturn));
+    naked_asm!("");
 }
 
 #[naked]
 pub unsafe fn rust_abi() {
     //~^ WARN Rust ABI is unsupported in naked functions
-    naked_asm!("", options(noreturn));
+    naked_asm!("");
 }
 
 #[naked]
 pub extern "C" fn valid_a<T>() -> T {
     unsafe {
-        naked_asm!("", options(noreturn));
+        naked_asm!("");
     }
 }
 
@@ -145,7 +146,7 @@ pub extern "C" fn valid_b() {
     unsafe {
         {
             {
-                naked_asm!("", options(noreturn));
+                naked_asm!("");
             };
         };
     }
@@ -153,13 +154,13 @@ pub extern "C" fn valid_b() {
 
 #[naked]
 pub unsafe extern "C" fn valid_c() {
-    naked_asm!("", options(noreturn));
+    naked_asm!("");
 }
 
 #[cfg(target_arch = "x86_64")]
 #[naked]
 pub unsafe extern "C" fn valid_att_syntax() {
-    naked_asm!("", options(noreturn, att_syntax));
+    naked_asm!("", options(att_syntax));
 }
 
 #[naked]
@@ -173,7 +174,7 @@ pub unsafe extern "C" fn allow_compile_error(a: u32) -> u32 {
 pub unsafe extern "C" fn allow_compile_error_and_asm(a: u32) -> u32 {
     compile_error!("this is a user specified error");
     //~^ ERROR this is a user specified error
-    naked_asm!("", options(noreturn))
+    naked_asm!("")
 }
 
 #[naked]
@@ -186,7 +187,7 @@ pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 {
 #[cfg_attr(target_pointer_width = "64", no_mangle)]
 #[naked]
 pub unsafe extern "C" fn compatible_cfg_attributes() {
-    naked_asm!("", options(noreturn, att_syntax));
+    naked_asm!("", options(att_syntax));
 }
 
 #[allow(dead_code)]
@@ -195,13 +196,13 @@ pub unsafe extern "C" fn compatible_cfg_attributes() {
 #[forbid(dead_code)]
 #[naked]
 pub unsafe extern "C" fn compatible_diagnostic_attributes() {
-    naked_asm!("", options(noreturn, raw));
+    naked_asm!("", options(raw));
 }
 
 #[deprecated = "test"]
 #[naked]
 pub unsafe extern "C" fn compatible_deprecated_attributes() {
-    naked_asm!("", options(noreturn, raw));
+    naked_asm!("", options(raw));
 }
 
 #[cfg(target_arch = "x86_64")]
@@ -213,7 +214,6 @@ pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
         mov rax, 42
         ret
         ",
-        options(noreturn)
     )
 }
 
@@ -222,20 +222,20 @@ pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
 #[no_mangle]
 #[naked]
 pub unsafe extern "C" fn compatible_ffi_attributes_1() {
-    naked_asm!("", options(noreturn, raw));
+    naked_asm!("", options(raw));
 }
 
 #[cold]
 #[naked]
 pub unsafe extern "C" fn compatible_codegen_attributes() {
-    naked_asm!("", options(noreturn, raw));
+    naked_asm!("", options(raw));
 }
 
 #[cfg(target_arch = "x86_64")]
 #[target_feature(enable = "sse2")]
 #[naked]
 pub unsafe extern "C" fn compatible_target_feature() {
-    naked_asm!("", options(noreturn));
+    naked_asm!("");
 }
 
 #[doc = "foo bar baz"]
@@ -244,11 +244,11 @@ pub unsafe extern "C" fn compatible_target_feature() {
 #[doc(alias = "ADocAlias")]
 #[naked]
 pub unsafe extern "C" fn compatible_doc_attributes() {
-    naked_asm!("", options(noreturn, raw));
+    naked_asm!("", options(raw));
 }
 
 #[linkage = "external"]
 #[naked]
 pub unsafe extern "C" fn compatible_linkage() {
-    naked_asm!("", options(noreturn, raw));
+    naked_asm!("", options(raw));
 }
diff --git a/tests/ui/asm/naked-functions.stderr b/tests/ui/asm/naked-functions.stderr
index 22c1946a960..1ceeafffd90 100644
--- a/tests/ui/asm/naked-functions.stderr
+++ b/tests/ui/asm/naked-functions.stderr
@@ -1,220 +1,184 @@
 error: the `in` operand cannot be used with `naked_asm!`
-  --> $DIR/naked-functions.rs:41:29
+  --> $DIR/naked-functions.rs:47:29
    |
-LL |     naked_asm!("/* {0} */", in(reg) a, options(noreturn))
+LL |     naked_asm!("/* {0} */", in(reg) a)
    |                             ^^ the `in` operand is not meaningful for global-scoped inline assembly, remove it
 
 error: the `in` operand cannot be used with `naked_asm!`
-  --> $DIR/naked-functions.rs:62:10
+  --> $DIR/naked-functions.rs:68:10
    |
 LL |          in(reg) a,
    |          ^^ the `in` operand is not meaningful for global-scoped inline assembly, remove it
 
+error: the `noreturn` option cannot be used with `naked_asm!`
+  --> $DIR/naked-functions.rs:88:32
+   |
+LL |         naked_asm!("", options(noreturn));
+   |                                ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly
+
 error: the `nomem` option cannot be used with `naked_asm!`
-  --> $DIR/naked-functions.rs:104:28
+  --> $DIR/naked-functions.rs:106:28
    |
-LL |     naked_asm!("", options(nomem, preserves_flags, noreturn));
+LL |     naked_asm!("", options(nomem, preserves_flags));
    |                            ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
 
 error: the `preserves_flags` option cannot be used with `naked_asm!`
-  --> $DIR/naked-functions.rs:104:35
+  --> $DIR/naked-functions.rs:106:35
    |
-LL |     naked_asm!("", options(nomem, preserves_flags, noreturn));
+LL |     naked_asm!("", options(nomem, preserves_flags));
    |                                   ^^^^^^^^^^^^^^^ the `preserves_flags` option is not meaningful for global-scoped inline assembly
 
 error: the `readonly` option cannot be used with `naked_asm!`
-  --> $DIR/naked-functions.rs:111:28
+  --> $DIR/naked-functions.rs:113:28
    |
 LL |     naked_asm!("", options(readonly, nostack), options(pure));
    |                            ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly
 
 error: the `nostack` option cannot be used with `naked_asm!`
-  --> $DIR/naked-functions.rs:111:38
+  --> $DIR/naked-functions.rs:113:38
    |
 LL |     naked_asm!("", options(readonly, nostack), options(pure));
    |                                      ^^^^^^^ the `nostack` option is not meaningful for global-scoped inline assembly
 
 error: the `pure` option cannot be used with `naked_asm!`
-  --> $DIR/naked-functions.rs:111:56
+  --> $DIR/naked-functions.rs:113:56
    |
 LL |     naked_asm!("", options(readonly, nostack), options(pure));
    |                                                        ^^^^ the `pure` option is not meaningful for global-scoped inline assembly
 
 error: the `may_unwind` option cannot be used with `naked_asm!`
-  --> $DIR/naked-functions.rs:120:38
+  --> $DIR/naked-functions.rs:121:28
    |
-LL |     naked_asm!("", options(noreturn, may_unwind));
-   |                                      ^^^^^^^^^^ the `may_unwind` option is not meaningful for global-scoped inline assembly
+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:168:5
+  --> $DIR/naked-functions.rs:169:5
    |
 LL |     compile_error!("this is a user specified error")
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this is a user specified error
-  --> $DIR/naked-functions.rs:174:5
+  --> $DIR/naked-functions.rs:175:5
    |
 LL |     compile_error!("this is a user specified error");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: asm template must be a string literal
-  --> $DIR/naked-functions.rs:181:16
+  --> $DIR/naked-functions.rs:182:16
    |
 LL |     naked_asm!(invalid_syntax)
    |                ^^^^^^^^^^^^^^
 
+error[E0787]: the `asm!` macro is not allowed in naked functions
+  --> $DIR/naked-functions.rs:13:5
+   |
+LL |     asm!("", options(raw));
+   |     ----^^^^^^^^^^^^^^^^^^
+   |     |
+   |     help: consider using the `naked_asm!` macro instead: `naked_asm!`
+
 error: patterns not allowed in naked function parameters
-  --> $DIR/naked-functions.rs:19:5
+  --> $DIR/naked-functions.rs:25:5
    |
 LL |     mut a: u32,
    |     ^^^^^
 
 error: patterns not allowed in naked function parameters
-  --> $DIR/naked-functions.rs:21:5
+  --> $DIR/naked-functions.rs:27:5
    |
 LL |     &b: &i32,
    |     ^^
 
 error: patterns not allowed in naked function parameters
-  --> $DIR/naked-functions.rs:23:6
+  --> $DIR/naked-functions.rs:29:6
    |
 LL |     (None | Some(_)): Option<std::ptr::NonNull<u8>>,
    |      ^^^^^^^^^^^^^^
 
 error: patterns not allowed in naked function parameters
-  --> $DIR/naked-functions.rs:25:5
+  --> $DIR/naked-functions.rs:31:5
    |
 LL |     P { x, y }: P,
    |     ^^^^^^^^^^
 
 error: referencing function parameters is not allowed in naked functions
-  --> $DIR/naked-functions.rs:34:5
+  --> $DIR/naked-functions.rs:40:5
    |
 LL |     a + 1
    |     ^
    |
    = help: follow the calling convention in asm block to use parameters
 
-error[E0787]: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:32:1
+error[E0787]: naked functions must contain a single `naked_asm!` invocation
+  --> $DIR/naked-functions.rs:38:1
    |
 LL | pub unsafe extern "C" fn inc(a: u32) -> u32 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     a + 1
-   |     ----- non-asm is unsupported in naked functions
+   |     ----- not allowed in naked functions
 
-error[E0787]: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:46:1
+error[E0787]: naked functions must contain a single `naked_asm!` invocation
+  --> $DIR/naked-functions.rs:52:1
    |
 LL | pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     (|| a + 1)()
-   |     ------------ non-asm is unsupported in naked functions
+   |     ------------ not allowed in naked functions
 
-error[E0787]: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:52:1
+error[E0787]: naked functions must contain a single `naked_asm!` invocation
+  --> $DIR/naked-functions.rs:58:1
    |
 LL | pub unsafe extern "C" fn unsupported_operands() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     let mut a = 0usize;
-   |     ------------------- non-asm is unsupported in naked functions
+   |     ------------------- not allowed in naked functions
 LL |     let mut b = 0usize;
-   |     ------------------- non-asm is unsupported in naked functions
+   |     ------------------- not allowed in naked functions
 LL |     let mut c = 0usize;
-   |     ------------------- non-asm is unsupported in naked functions
+   |     ------------------- not allowed in naked functions
 LL |     let mut d = 0usize;
-   |     ------------------- non-asm is unsupported in naked functions
+   |     ------------------- not allowed in naked functions
 LL |     let mut e = 0usize;
-   |     ------------------- non-asm is unsupported in naked functions
+   |     ------------------- not allowed in naked functions
 
-error[E0787]: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:74:1
+error[E0787]: naked functions must contain a single `naked_asm!` invocation
+  --> $DIR/naked-functions.rs:80:1
    |
 LL | pub extern "C" fn missing_assembly() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0787]: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:82:9
-   |
-LL |         naked_asm!("");
-   |         ^^^^^^^^^^^^^^
-   |
-help: consider specifying that the asm block is responsible for returning from the function
-   |
-LL |         naked_asm!("", options(noreturn));
-   |                      +++++++++++++++++++
-
-error[E0787]: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:84:9
-   |
-LL |         naked_asm!("");
-   |         ^^^^^^^^^^^^^^
-   |
-help: consider specifying that the asm block is responsible for returning from the function
-   |
-LL |         naked_asm!("", options(noreturn));
-   |                      +++++++++++++++++++
-
-error[E0787]: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:86:9
-   |
-LL |         naked_asm!("");
-   |         ^^^^^^^^^^^^^^
-   |
-help: consider specifying that the asm block is responsible for returning from the function
-   |
-LL |         naked_asm!("", options(noreturn));
-   |                      +++++++++++++++++++
-
-error[E0787]: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:79:1
+error[E0787]: naked functions must contain a single `naked_asm!` invocation
+  --> $DIR/naked-functions.rs:85:1
    |
 LL | pub extern "C" fn too_many_asm_blocks() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 ...
 LL |         naked_asm!("");
-   |         -------------- multiple asm blocks are unsupported in naked functions
-LL |
-LL |         naked_asm!("");
-   |         -------------- multiple asm blocks are unsupported in naked functions
-LL |
-LL |         naked_asm!("", options(noreturn));
-   |         --------------------------------- multiple asm blocks are unsupported in naked functions
+   |         -------------- multiple `naked_asm!` invocations are not allowed in naked functions
 
 error: referencing function parameters is not allowed in naked functions
-  --> $DIR/naked-functions.rs:96:11
+  --> $DIR/naked-functions.rs:98:11
    |
 LL |         *&y
    |           ^
    |
    = help: follow the calling convention in asm block to use parameters
 
-error[E0787]: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:94:5
+error[E0787]: naked functions must contain a single `naked_asm!` invocation
+  --> $DIR/naked-functions.rs:96:5
    |
 LL |     pub extern "C" fn inner(y: usize) -> usize {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |         *&y
-   |         --- non-asm is unsupported in naked functions
-
-error[E0787]: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:111:5
-   |
-LL |     naked_asm!("", options(readonly, nostack), options(pure));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: consider specifying that the asm block is responsible for returning from the function
-   |
-LL |     naked_asm!("", options(noreturn), options(readonly, nostack), options(pure));
-   |                  +++++++++++++++++++
+   |         --- not allowed in naked functions
 
 warning: Rust ABI is unsupported in naked functions
-  --> $DIR/naked-functions.rs:125:1
+  --> $DIR/naked-functions.rs:126:1
    |
 LL | pub unsafe fn default_abi() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -222,11 +186,11 @@ 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:131:1
+  --> $DIR/naked-functions.rs:132:1
    |
 LL | pub unsafe fn rust_abi() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 27 previous errors; 2 warnings emitted
+error: aborting due to 25 previous errors; 2 warnings emitted
 
 For more information about this error, try `rustc --explain E0787`.
diff --git a/tests/ui/asm/naked-invalid-attr.rs b/tests/ui/asm/naked-invalid-attr.rs
index 57edd57de99..4053c58fb51 100644
--- a/tests/ui/asm/naked-invalid-attr.rs
+++ b/tests/ui/asm/naked-invalid-attr.rs
@@ -4,7 +4,7 @@
 #![feature(naked_functions)]
 #![naked] //~ ERROR should be applied to a function definition
 
-use std::arch::asm;
+use std::arch::naked_asm;
 
 extern "C" {
     #[naked] //~ ERROR should be applied to a function definition
@@ -26,27 +26,28 @@ trait Invoke {
 impl Invoke for S {
     #[naked]
     extern "C" fn invoke(&self) {
-        unsafe { asm!("", options(noreturn)) }
+        unsafe { naked_asm!("") }
     }
 }
 
 #[naked]
 extern "C" fn ok() {
-    unsafe { asm!("", options(noreturn)) }
+    unsafe { naked_asm!("") }
 }
 
 impl S {
     #[naked]
     extern "C" fn g() {
-        unsafe { asm!("", options(noreturn)) }
+        unsafe { naked_asm!("") }
     }
 
     #[naked]
     extern "C" fn h(&self) {
-        unsafe { asm!("", options(noreturn)) }
+        unsafe { naked_asm!("") }
     }
 }
 
 fn main() {
-    #[naked] || {}; //~ ERROR should be applied to a function definition
+    #[naked] //~ ERROR should be applied to a function definition
+    || {};
 }
diff --git a/tests/ui/asm/naked-invalid-attr.stderr b/tests/ui/asm/naked-invalid-attr.stderr
index e8ddccc854a..640f9d9510d 100644
--- a/tests/ui/asm/naked-invalid-attr.stderr
+++ b/tests/ui/asm/naked-invalid-attr.stderr
@@ -13,8 +13,10 @@ LL | | }
 error: attribute should be applied to a function definition
   --> $DIR/naked-invalid-attr.rs:51:5
    |
-LL |     #[naked] || {};
-   |     ^^^^^^^^ ----- not a function definition
+LL |     #[naked]
+   |     ^^^^^^^^
+LL |     || {};
+   |     ----- not a function definition
 
 error: attribute should be applied to a function definition
   --> $DIR/naked-invalid-attr.rs:22:5
diff --git a/tests/ui/asm/naked-with-invalid-repr-attr.rs b/tests/ui/asm/naked-with-invalid-repr-attr.rs
index 687fe1ad73d..18b9c1014c3 100644
--- a/tests/ui/asm/naked-with-invalid-repr-attr.rs
+++ b/tests/ui/asm/naked-with-invalid-repr-attr.rs
@@ -2,14 +2,14 @@
 #![feature(naked_functions)]
 #![feature(fn_align)]
 #![crate_type = "lib"]
-use std::arch::asm;
+use std::arch::naked_asm;
 
 #[repr(C)]
 //~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
 #[naked]
 extern "C" fn example1() {
     //~^ NOTE not a struct, enum, or union
-    unsafe { asm!("", options(noreturn)) }
+    unsafe { naked_asm!("") }
 }
 
 #[repr(transparent)]
@@ -17,7 +17,7 @@ extern "C" fn example1() {
 #[naked]
 extern "C" fn example2() {
     //~^ NOTE not a struct, enum, or union
-    unsafe { asm!("", options(noreturn)) }
+    unsafe { naked_asm!("") }
 }
 
 #[repr(align(16), C)]
@@ -25,7 +25,7 @@ extern "C" fn example2() {
 #[naked]
 extern "C" fn example3() {
     //~^ NOTE not a struct, enum, or union
-    unsafe { asm!("", options(noreturn)) }
+    unsafe { naked_asm!("") }
 }
 
 // note: two errors because of packed and C
@@ -36,7 +36,7 @@ extern "C" fn example3() {
 extern "C" fn example4() {
     //~^ NOTE not a struct, enum, or union
     //~| NOTE not a struct or union
-    unsafe { asm!("", options(noreturn)) }
+    unsafe { naked_asm!("") }
 }
 
 #[repr(u8)]
@@ -44,5 +44,5 @@ extern "C" fn example4() {
 #[naked]
 extern "C" fn example5() {
     //~^ NOTE not an enum
-    unsafe { asm!("", options(noreturn)) }
+    unsafe { naked_asm!("") }
 }
diff --git a/tests/ui/asm/naked-with-invalid-repr-attr.stderr b/tests/ui/asm/naked-with-invalid-repr-attr.stderr
index 3740f17a9dc..8248a8c1657 100644
--- a/tests/ui/asm/naked-with-invalid-repr-attr.stderr
+++ b/tests/ui/asm/naked-with-invalid-repr-attr.stderr
@@ -6,7 +6,7 @@ LL |   #[repr(C)]
 ...
 LL | / extern "C" fn example1() {
 LL | |
-LL | |     unsafe { asm!("", options(noreturn)) }
+LL | |     unsafe { naked_asm!("") }
 LL | | }
    | |_- not a struct, enum, or union
 
@@ -18,7 +18,7 @@ LL |   #[repr(transparent)]
 ...
 LL | / extern "C" fn example2() {
 LL | |
-LL | |     unsafe { asm!("", options(noreturn)) }
+LL | |     unsafe { naked_asm!("") }
 LL | | }
    | |_- not a struct, enum, or union
 
@@ -30,7 +30,7 @@ LL |   #[repr(align(16), C)]
 ...
 LL | / extern "C" fn example3() {
 LL | |
-LL | |     unsafe { asm!("", options(noreturn)) }
+LL | |     unsafe { naked_asm!("") }
 LL | | }
    | |_- not a struct, enum, or union
 
@@ -43,7 +43,7 @@ LL |   #[repr(C, packed)]
 LL | / extern "C" fn example4() {
 LL | |
 LL | |
-LL | |     unsafe { asm!("", options(noreturn)) }
+LL | |     unsafe { naked_asm!("") }
 LL | | }
    | |_- not a struct, enum, or union
 
@@ -56,7 +56,7 @@ LL |   #[repr(C, packed)]
 LL | / extern "C" fn example4() {
 LL | |
 LL | |
-LL | |     unsafe { asm!("", options(noreturn)) }
+LL | |     unsafe { naked_asm!("") }
 LL | | }
    | |_- not a struct or union
 
@@ -68,7 +68,7 @@ LL |   #[repr(u8)]
 ...
 LL | / extern "C" fn example5() {
 LL | |
-LL | |     unsafe { asm!("", options(noreturn)) }
+LL | |     unsafe { naked_asm!("") }
 LL | | }
    | |_- not an enum
 
diff --git a/tests/ui/asm/named-asm-labels.rs b/tests/ui/asm/named-asm-labels.rs
index 043aab9029d..77831e679ed 100644
--- a/tests/ui/asm/named-asm-labels.rs
+++ b/tests/ui/asm/named-asm-labels.rs
@@ -12,7 +12,7 @@
 
 #![feature(naked_functions)]
 
-use std::arch::{asm, global_asm};
+use std::arch::{asm, global_asm, naked_asm};
 
 #[no_mangle]
 pub static FOO: usize = 42;
@@ -177,7 +177,7 @@ fn main() {
 // label or LTO can cause labels to break
 #[naked]
 pub extern "C" fn foo() -> i32 {
-    unsafe { asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1, options(noreturn)) }
+    unsafe { naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1) }
     //~^ ERROR avoid using named labels
 }
 
@@ -192,7 +192,7 @@ pub extern "C" fn bar() {
 pub extern "C" fn aaa() {
     fn _local() {}
 
-    unsafe { asm!(".Laaa: nop; ret;", options(noreturn)) } //~ ERROR avoid using named labels
+    unsafe { naked_asm!(".Laaa: nop; ret;") } //~ ERROR avoid using named labels
 }
 
 pub fn normal() {
@@ -202,7 +202,7 @@ pub fn normal() {
     pub extern "C" fn bbb() {
         fn _very_local() {}
 
-        unsafe { asm!(".Lbbb: nop; ret;", options(noreturn)) } //~ ERROR avoid using named labels
+        unsafe { naked_asm!(".Lbbb: nop; ret;") } //~ ERROR avoid using named labels
     }
 
     fn _local2() {}
@@ -221,7 +221,7 @@ fn closures() {
     || {
         #[naked]
         unsafe extern "C" fn _nested() {
-            asm!("ret;", options(noreturn));
+            naked_asm!("ret;");
         }
 
         unsafe {
diff --git a/tests/ui/asm/named-asm-labels.stderr b/tests/ui/asm/named-asm-labels.stderr
index e5e177fb8b8..44ce358c62b 100644
--- a/tests/ui/asm/named-asm-labels.stderr
+++ b/tests/ui/asm/named-asm-labels.stderr
@@ -475,10 +475,10 @@ LL |         #[warn(named_asm_labels)]
    |                ^^^^^^^^^^^^^^^^
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:180:20
+  --> $DIR/named-asm-labels.rs:180:26
    |
-LL |     unsafe { asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1, options(noreturn)) }
-   |                    ^^^^^
+LL |     unsafe { naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1) }
+   |                          ^^^^^
    |
    = help: only local labels of the form `<number>:` should be used in inline asm
    = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
@@ -493,19 +493,19 @@ LL |     unsafe { asm!(".Lbar: mov rax, {}; ret;", "nop", const 1, options(noret
    = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:195:20
+  --> $DIR/named-asm-labels.rs:195:26
    |
-LL |     unsafe { asm!(".Laaa: nop; ret;", options(noreturn)) }
-   |                    ^^^^^
+LL |     unsafe { naked_asm!(".Laaa: nop; ret;") }
+   |                          ^^^^^
    |
    = help: only local labels of the form `<number>:` should be used in inline asm
    = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:205:24
+  --> $DIR/named-asm-labels.rs:205:30
    |
-LL |         unsafe { asm!(".Lbbb: nop; ret;", options(noreturn)) }
-   |                        ^^^^^
+LL |         unsafe { naked_asm!(".Lbbb: nop; ret;") }
+   |                              ^^^^^
    |
    = help: only local labels of the form `<number>:` should be used in inline asm
    = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
diff --git a/tests/ui/feature-gates/feature-gate-naked_functions.rs b/tests/ui/feature-gates/feature-gate-naked_functions.rs
index c8802ea4c31..5fe0bbdc774 100644
--- a/tests/ui/feature-gates/feature-gate-naked_functions.rs
+++ b/tests/ui/feature-gates/feature-gate-naked_functions.rs
@@ -6,7 +6,7 @@ use std::arch::naked_asm;
 #[naked]
 //~^ the `#[naked]` attribute is an experimental feature
 extern "C" fn naked() {
-    naked_asm!("", options(noreturn))
+    naked_asm!("")
     //~^ ERROR use of unstable library feature 'naked_functions'
     //~| ERROR: requires unsafe
 }
@@ -14,7 +14,7 @@ extern "C" fn naked() {
 #[naked]
 //~^ the `#[naked]` attribute is an experimental feature
 extern "C" fn naked_2() -> isize {
-    naked_asm!("", options(noreturn))
+    naked_asm!("")
     //~^ ERROR use of unstable library feature 'naked_functions'
     //~| ERROR: requires unsafe
 }