From 41ddf8672231c1f8cfa0fc754c1653f151030b19 Mon Sep 17 00:00:00 2001
From: Folkert de Vries <folkert@folkertdev.nl>
Date: Sat, 29 Mar 2025 17:30:11 +0100
Subject: [PATCH] Make `#[naked]` an unsafe attribute

---
 compiler/rustc_builtin_macros/messages.ftl    |  4 +-
 .../example/mini_core_hello_world.rs          |  6 +-
 .../src/error_codes/E0736.md                  |  2 +-
 .../src/error_codes/E0787.md                  |  2 +-
 compiler/rustc_feature/src/builtin_attrs.rs   |  2 +-
 .../rustc_mir_build/src/check_unsafety.rs     |  8 ++-
 compiler/rustc_parse/src/validate_attr.rs     |  6 --
 compiler/rustc_passes/messages.ftl            |  8 +--
 .../src/compiler-flags/sanitizer.md           | 37 +++++------
 .../aarch64-naked-fn-no-bti-prolog.rs         |  4 +-
 tests/assembly/naked-functions/aix.rs         |  4 +-
 tests/assembly/naked-functions/wasm32.rs      | 60 +++++++++---------
 .../x86_64-naked-fn-no-cet-prolog.rs          |  4 +-
 tests/codegen/cffi/c-variadic-naked.rs        |  6 +-
 tests/codegen/naked-asan.rs                   |  4 +-
 tests/codegen/naked-fn/aligned.rs             |  6 +-
 tests/codegen/naked-fn/generics.rs            | 46 +++++++-------
 tests/codegen/naked-fn/instruction-set.rs     | 12 ++--
 .../naked-fn/min-function-alignment.rs        | 16 ++---
 tests/codegen/naked-fn/naked-functions.rs     | 16 ++---
 .../naked-symbol-visibility/a_rust_dylib.rs   | 20 +++---
 tests/ui/asm/naked-asm-outside-naked-fn.rs    | 16 ++---
 .../ui/asm/naked-asm-outside-naked-fn.stderr  | 24 +++----
 tests/ui/asm/naked-functions-ffi.rs           |  6 +-
 tests/ui/asm/naked-functions-inline.rs        | 20 +++---
 tests/ui/asm/naked-functions-inline.stderr    | 32 +++++-----
 .../ui/asm/naked-functions-instruction-set.rs |  8 +--
 tests/ui/asm/naked-functions-rustic-abi.rs    | 12 ++--
 .../ui/asm/naked-functions-target-feature.rs  | 12 ++--
 tests/ui/asm/naked-functions-testattrs.rs     | 16 ++---
 tests/ui/asm/naked-functions-testattrs.stderr | 24 +++----
 tests/ui/asm/naked-functions-unused.rs        | 30 +++------
 tests/ui/asm/naked-functions.rs               | 62 +++++++++----------
 tests/ui/asm/naked-functions.stderr           | 50 +++++++--------
 tests/ui/asm/naked-invalid-attr.rs            | 28 ++++-----
 tests/ui/asm/naked-invalid-attr.stderr        | 20 +++---
 tests/ui/asm/naked-with-invalid-repr-attr.rs  | 20 +++---
 .../asm/naked-with-invalid-repr-attr.stderr   | 12 ++--
 tests/ui/asm/named-asm-labels.rs              | 16 ++---
 tests/ui/asm/named-asm-labels.stderr          | 18 +++---
 .../feature-gate-naked_functions.rs           |  6 +-
 .../feature-gate-naked_functions.stderr       | 45 ++++++++------
 ...feature-gate-naked_functions_rustic_abi.rs |  6 +-
 ...ure-gate-naked_functions_target_feature.rs |  2 +-
 .../rfc-2091-track-caller/error-with-naked.rs |  4 +-
 .../error-with-naked.stderr                   | 16 ++---
 46 files changed, 375 insertions(+), 403 deletions(-)

diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index 5316e90847ac5..73be954cefd76 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -247,9 +247,9 @@ builtin_macros_multiple_defaults = multiple declared defaults
     .suggestion = make `{$ident}` default
 
 builtin_macros_naked_functions_testing_attribute =
-    cannot use `#[naked]` with testing attributes
+    cannot use `#[unsafe(naked)]` with testing attributes
     .label = function marked with testing attribute here
-    .naked_attribute = `#[naked]` is incompatible with testing attributes
+    .naked_attribute = `#[unsafe(naked)]` is incompatible with testing attributes
 
 builtin_macros_no_default_variant = `#[derive(Default)]` on enum with no `#[default]`
     .label = this enum needs a unit variant marked with `#[default]`
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
index 09d5b73fd3d9d..0b3a7281d5a06 100644
--- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
+++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
@@ -387,11 +387,9 @@ global_asm! {
 }
 
 #[cfg(all(not(jit), target_arch = "x86_64"))]
-#[naked]
+#[unsafe(naked)]
 extern "C" fn naked_test() {
-    unsafe {
-        naked_asm!("ret");
-    }
+    naked_asm!("ret")
 }
 
 #[repr(C)]
diff --git a/compiler/rustc_error_codes/src/error_codes/E0736.md b/compiler/rustc_error_codes/src/error_codes/E0736.md
index cb7633b7068a3..66d5fbb80cf29 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0736.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0736.md
@@ -11,7 +11,7 @@ Erroneous code example:
 
 ```compile_fail,E0736
 #[inline]
-#[naked]
+#[unsafe(naked)]
 fn foo() {}
 ```
 
diff --git a/compiler/rustc_error_codes/src/error_codes/E0787.md b/compiler/rustc_error_codes/src/error_codes/E0787.md
index f5c5faa066b6b..47b56ac17f4f5 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0787.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0787.md
@@ -5,7 +5,7 @@ Erroneous code example:
 ```compile_fail,E0787
 #![feature(naked_functions)]
 
-#[naked]
+#[unsafe(naked)]
 pub extern "C" fn f() -> u32 {
     42
 }
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 3b441729d7552..713e460e507f4 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -517,7 +517,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
 
     // Linking:
     gated!(
-        naked, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
+        unsafe naked, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
         naked_functions, experimental!(naked)
     ),
 
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index b6a856a6eb4d1..adfce99a9b537 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -564,13 +564,17 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 }
             }
             ExprKind::InlineAsm(box InlineAsmExpr {
-                asm_macro: AsmMacro::Asm | AsmMacro::NakedAsm,
+                asm_macro: asm_macro @ (AsmMacro::Asm | AsmMacro::NakedAsm),
                 ref operands,
                 template: _,
                 options: _,
                 line_spans: _,
             }) => {
-                self.requires_unsafe(expr.span, UseOfInlineAssembly);
+                // The `naked` attribute and the `naked_asm!` block form one atomic unit of
+                // unsafety, and `naked_asm!` does not itself need to be wrapped in an unsafe block.
+                if let AsmMacro::Asm = asm_macro {
+                    self.requires_unsafe(expr.span, UseOfInlineAssembly);
+                }
 
                 // For inline asm, do not use `walk_expr`, since we want to handle the label block
                 // specially.
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index b518fca7a6583..6a1c2af48ed50 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -194,12 +194,6 @@ pub fn check_attribute_safety(psess: &ParseSess, safety: AttributeSafety, attr:
             }
         }
     } else if let Safety::Unsafe(unsafe_span) = attr_item.unsafety {
-        // Allow (but don't require) `#[unsafe(naked)]` so that compiler-builtins can upgrade to it.
-        // FIXME(#139797): remove this special case when compiler-builtins has upgraded.
-        if attr.has_name(sym::naked) {
-            return;
-        }
-
         psess.dcx().emit_err(errors::InvalidAttrUnsafe {
             span: unsafe_span,
             name: attr_item.path.clone(),
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 99789b74488c9..413726ddd82d3 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -508,7 +508,7 @@ passes_must_use_no_effect =
     `#[must_use]` has no effect when applied to {$article} {$target}
 
 passes_naked_asm_outside_naked_fn =
-    the `naked_asm!` macro can only be used in functions marked with `#[naked]`
+    the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]`
 
 passes_naked_functions_asm_block =
     naked functions must contain a single `naked_asm!` invocation
@@ -516,9 +516,9 @@ passes_naked_functions_asm_block =
     .label_non_asm = not allowed in naked functions
 
 passes_naked_functions_incompatible_attribute =
-    attribute incompatible with `#[naked]`
-    .label = the `{$attr}` attribute is incompatible with `#[naked]`
-    .naked_attribute = function marked with `#[naked]` here
+    attribute incompatible with `#[unsafe(naked)]`
+    .label = the `{$attr}` attribute is incompatible with `#[unsafe(naked)]`
+    .naked_attribute = function marked with `#[unsafe(naked)]` here
 
 passes_naked_functions_must_naked_asm =
     the `asm!` macro is not allowed in naked functions
diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md
index 4679acf0a6a15..f2e1bb80cb263 100644
--- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md
+++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md
@@ -247,34 +247,31 @@ See the [Clang ControlFlowIntegrity documentation][clang-cfi] for more details.
 ```rust,ignore (making doc tests pass cross-platform is hard)
 #![feature(naked_functions)]
 
-use std::arch::asm;
+use std::arch::naked_asm;
 use std::mem;
 
 fn add_one(x: i32) -> i32 {
     x + 1
 }
 
-#[naked]
+#[unsafe(naked)]
 pub extern "C" fn add_two(x: i32) {
     // x + 2 preceded by a landing pad/nop block
-    unsafe {
-        asm!(
-            "
-             nop
-             nop
-             nop
-             nop
-             nop
-             nop
-             nop
-             nop
-             nop
-             lea eax, [rdi+2]
-             ret
-        ",
-            options(noreturn)
-        );
-    }
+    naked_asm!(
+        "
+         nop
+         nop
+         nop
+         nop
+         nop
+         nop
+         nop
+         nop
+         nop
+         lea eax, [rdi+2]
+         ret
+        "
+    );
 }
 
 fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
diff --git a/tests/assembly/naked-functions/aarch64-naked-fn-no-bti-prolog.rs b/tests/assembly/naked-functions/aarch64-naked-fn-no-bti-prolog.rs
index 46e627eaa00bd..46acf7c6501a9 100644
--- a/tests/assembly/naked-functions/aarch64-naked-fn-no-bti-prolog.rs
+++ b/tests/assembly/naked-functions/aarch64-naked-fn-no-bti-prolog.rs
@@ -13,8 +13,8 @@ use std::arch::naked_asm;
 // LLVM implements this via making sure of that, even for functions with the naked attribute.
 // So, we must emit an appropriate instruction instead!
 #[no_mangle]
-#[naked]
-pub unsafe extern "C" fn _hlt() -> ! {
+#[unsafe(naked)]
+pub extern "C" fn _hlt() -> ! {
     // CHECK-NOT: hint #34
     // CHECK: hlt #0x1
     naked_asm!("hlt #1")
diff --git a/tests/assembly/naked-functions/aix.rs b/tests/assembly/naked-functions/aix.rs
index cc0825b37387c..9aa9edc39e78b 100644
--- a/tests/assembly/naked-functions/aix.rs
+++ b/tests/assembly/naked-functions/aix.rs
@@ -29,7 +29,7 @@ use minicore::*;
 // CHECK-LABEL: blr:
 // CHECK: blr
 #[no_mangle]
-#[naked]
-unsafe extern "C" fn blr() {
+#[unsafe(naked)]
+extern "C" fn blr() {
     naked_asm!("blr")
 }
diff --git a/tests/assembly/naked-functions/wasm32.rs b/tests/assembly/naked-functions/wasm32.rs
index 4911a6bd08f68..c114cb385be17 100644
--- a/tests/assembly/naked-functions/wasm32.rs
+++ b/tests/assembly/naked-functions/wasm32.rs
@@ -22,8 +22,8 @@ use minicore::*;
 // CHECK-NOT: .size
 // CHECK: end_function
 #[no_mangle]
-#[naked]
-unsafe extern "C" fn nop() {
+#[unsafe(naked)]
+extern "C" fn nop() {
     naked_asm!("nop")
 }
 
@@ -34,11 +34,11 @@ unsafe extern "C" fn nop() {
 // CHECK-NOT: .size
 // CHECK: end_function
 #[no_mangle]
-#[naked]
+#[unsafe(naked)]
 #[linkage = "weak"]
 // wasm functions cannot be aligned, so this has no effect
 #[repr(align(32))]
-unsafe extern "C" fn weak_aligned_nop() {
+extern "C" fn weak_aligned_nop() {
     naked_asm!("nop")
 }
 
@@ -51,48 +51,48 @@ unsafe extern "C" fn weak_aligned_nop() {
 //
 // CHECK-NEXT: end_function
 #[no_mangle]
-#[naked]
-unsafe extern "C" fn fn_i8_i8(num: i8) -> i8 {
+#[unsafe(naked)]
+extern "C" fn fn_i8_i8(num: i8) -> i8 {
     naked_asm!("local.get 0", "local.get 0", "i32.mul")
 }
 
 // CHECK-LABEL: fn_i8_i8_i8:
 // CHECK: .functype fn_i8_i8_i8 (i32, i32) -> (i32)
 #[no_mangle]
-#[naked]
-unsafe extern "C" fn fn_i8_i8_i8(a: i8, b: i8) -> i8 {
+#[unsafe(naked)]
+extern "C" fn fn_i8_i8_i8(a: i8, b: i8) -> i8 {
     naked_asm!("local.get 1", "local.get 0", "i32.mul")
 }
 
 // CHECK-LABEL: fn_unit_i8:
 // CHECK: .functype fn_unit_i8 () -> (i32)
 #[no_mangle]
-#[naked]
-unsafe extern "C" fn fn_unit_i8() -> i8 {
+#[unsafe(naked)]
+extern "C" fn fn_unit_i8() -> i8 {
     naked_asm!("i32.const 42")
 }
 
 // CHECK-LABEL: fn_i8_unit:
 // CHECK: .functype fn_i8_unit (i32) -> ()
 #[no_mangle]
-#[naked]
-unsafe extern "C" fn fn_i8_unit(_: i8) {
+#[unsafe(naked)]
+extern "C" fn fn_i8_unit(_: i8) {
     naked_asm!("nop")
 }
 
 // CHECK-LABEL: fn_i32_i32:
 // CHECK: .functype fn_i32_i32 (i32) -> (i32)
 #[no_mangle]
-#[naked]
-unsafe extern "C" fn fn_i32_i32(num: i32) -> i32 {
+#[unsafe(naked)]
+extern "C" fn fn_i32_i32(num: i32) -> i32 {
     naked_asm!("local.get 0", "local.get 0", "i32.mul")
 }
 
 // CHECK-LABEL: fn_i64_i64:
 // CHECK: .functype fn_i64_i64 (i64) -> (i64)
 #[no_mangle]
-#[naked]
-unsafe extern "C" fn fn_i64_i64(num: i64) -> i64 {
+#[unsafe(naked)]
+extern "C" fn fn_i64_i64(num: i64) -> i64 {
     naked_asm!("local.get 0", "local.get 0", "i64.mul")
 }
 
@@ -101,8 +101,8 @@ unsafe extern "C" fn fn_i64_i64(num: i64) -> i64 {
 // wasm64-unknown: .functype fn_i128_i128 (i64, i64, i64) -> ()
 #[allow(improper_ctypes_definitions)]
 #[no_mangle]
-#[naked]
-unsafe extern "C" fn fn_i128_i128(num: i128) -> i128 {
+#[unsafe(naked)]
+extern "C" fn fn_i128_i128(num: i128) -> i128 {
     naked_asm!(
         "local.get       0",
         "local.get       2",
@@ -117,8 +117,8 @@ unsafe extern "C" fn fn_i128_i128(num: i128) -> i128 {
 // wasm32-wasip1: .functype fn_f128_f128 (i32, i64, i64) -> ()
 // wasm64-unknown: .functype fn_f128_f128 (i64, i64, i64) -> ()
 #[no_mangle]
-#[naked]
-unsafe extern "C" fn fn_f128_f128(num: f128) -> f128 {
+#[unsafe(naked)]
+extern "C" fn fn_f128_f128(num: f128) -> f128 {
     naked_asm!(
         "local.get       0",
         "local.get       2",
@@ -139,8 +139,8 @@ struct Compound {
 // wasm32-wasip1: .functype fn_compound_compound (i32, i32) -> ()
 // wasm64-unknown: .functype fn_compound_compound (i64, i64) -> ()
 #[no_mangle]
-#[naked]
-unsafe extern "C" fn fn_compound_compound(_: Compound) -> Compound {
+#[unsafe(naked)]
+extern "C" fn fn_compound_compound(_: Compound) -> Compound {
     // this is the wasm32-wasip1 assembly
     naked_asm!(
         "local.get       0",
@@ -160,8 +160,8 @@ struct WrapperI32(i32);
 // CHECK-LABEL: fn_wrapperi32_wrapperi32:
 // CHECK: .functype fn_wrapperi32_wrapperi32 (i32) -> (i32)
 #[no_mangle]
-#[naked]
-unsafe extern "C" fn fn_wrapperi32_wrapperi32(_: WrapperI32) -> WrapperI32 {
+#[unsafe(naked)]
+extern "C" fn fn_wrapperi32_wrapperi32(_: WrapperI32) -> WrapperI32 {
     naked_asm!("local.get       0")
 }
 
@@ -171,8 +171,8 @@ struct WrapperI64(i64);
 // CHECK-LABEL: fn_wrapperi64_wrapperi64:
 // CHECK: .functype fn_wrapperi64_wrapperi64 (i64) -> (i64)
 #[no_mangle]
-#[naked]
-unsafe extern "C" fn fn_wrapperi64_wrapperi64(_: WrapperI64) -> WrapperI64 {
+#[unsafe(naked)]
+extern "C" fn fn_wrapperi64_wrapperi64(_: WrapperI64) -> WrapperI64 {
     naked_asm!("local.get       0")
 }
 
@@ -182,8 +182,8 @@ struct WrapperF32(f32);
 // CHECK-LABEL: fn_wrapperf32_wrapperf32:
 // CHECK: .functype fn_wrapperf32_wrapperf32 (f32) -> (f32)
 #[no_mangle]
-#[naked]
-unsafe extern "C" fn fn_wrapperf32_wrapperf32(_: WrapperF32) -> WrapperF32 {
+#[unsafe(naked)]
+extern "C" fn fn_wrapperf32_wrapperf32(_: WrapperF32) -> WrapperF32 {
     naked_asm!("local.get       0")
 }
 
@@ -193,7 +193,7 @@ struct WrapperF64(f64);
 // CHECK-LABEL: fn_wrapperf64_wrapperf64:
 // CHECK: .functype fn_wrapperf64_wrapperf64 (f64) -> (f64)
 #[no_mangle]
-#[naked]
-unsafe extern "C" fn fn_wrapperf64_wrapperf64(_: WrapperF64) -> WrapperF64 {
+#[unsafe(naked)]
+extern "C" fn fn_wrapperf64_wrapperf64(_: WrapperF64) -> WrapperF64 {
     naked_asm!("local.get       0")
 }
diff --git a/tests/assembly/naked-functions/x86_64-naked-fn-no-cet-prolog.rs b/tests/assembly/naked-functions/x86_64-naked-fn-no-cet-prolog.rs
index 54e1d93c68bd6..df6a2e91c51ea 100644
--- a/tests/assembly/naked-functions/x86_64-naked-fn-no-cet-prolog.rs
+++ b/tests/assembly/naked-functions/x86_64-naked-fn-no-cet-prolog.rs
@@ -13,8 +13,8 @@ use std::arch::naked_asm;
 // works by using an instruction for each possible landing site,
 // and LLVM implements this via making sure of that.
 #[no_mangle]
-#[naked]
-pub unsafe extern "sysv64" fn will_halt() -> ! {
+#[unsafe(naked)]
+pub extern "sysv64" fn will_halt() -> ! {
     // CHECK-NOT: endbr{{32|64}}
     // CHECK: hlt
     naked_asm!("hlt")
diff --git a/tests/codegen/cffi/c-variadic-naked.rs b/tests/codegen/cffi/c-variadic-naked.rs
index 24b69c5f59e21..05d48e52dc006 100644
--- a/tests/codegen/cffi/c-variadic-naked.rs
+++ b/tests/codegen/cffi/c-variadic-naked.rs
@@ -8,11 +8,9 @@
 #![feature(naked_functions)]
 #![no_std]
 
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "C" fn c_variadic(_: usize, _: ...) {
     // CHECK-NOT: va_start
     // CHECK-NOT: alloca
-    core::arch::naked_asm! {
-        "ret",
-    }
+    core::arch::naked_asm!("ret")
 }
diff --git a/tests/codegen/naked-asan.rs b/tests/codegen/naked-asan.rs
index 8efedab6ea55d..52b3e709cd35c 100644
--- a/tests/codegen/naked-asan.rs
+++ b/tests/codegen/naked-asan.rs
@@ -13,10 +13,10 @@ pub fn caller() {
 }
 
 // CHECK: declare x86_intrcc void @page_fault_handler(ptr {{.*}}, i64{{.*}}){{.*}}#[[ATTRS:[0-9]+]]
-#[naked]
+#[unsafe(naked)]
 #[no_mangle]
 pub extern "x86-interrupt" fn page_fault_handler(_: u64, _: u64) {
-    unsafe { core::arch::naked_asm!("ud2") };
+    core::arch::naked_asm!("ud2")
 }
 
 // CHECK: #[[ATTRS]] =
diff --git a/tests/codegen/naked-fn/aligned.rs b/tests/codegen/naked-fn/aligned.rs
index d9dcd7f6c3ef7..6183461fedaec 100644
--- a/tests/codegen/naked-fn/aligned.rs
+++ b/tests/codegen/naked-fn/aligned.rs
@@ -10,8 +10,8 @@ use std::arch::naked_asm;
 // CHECK-LABEL: naked_empty:
 #[repr(align(16))]
 #[no_mangle]
-#[naked]
-pub unsafe extern "C" fn naked_empty() {
+#[unsafe(naked)]
+pub extern "C" fn naked_empty() {
     // CHECK: ret
-    naked_asm!("ret");
+    naked_asm!("ret")
 }
diff --git a/tests/codegen/naked-fn/generics.rs b/tests/codegen/naked-fn/generics.rs
index 64998df64ddb6..4427586777168 100644
--- a/tests/codegen/naked-fn/generics.rs
+++ b/tests/codegen/naked-fn/generics.rs
@@ -28,21 +28,19 @@ fn test(x: u64) {
 // CHECK: add rax, 1
 // CHECK: add rax, 42
 
-#[naked]
+#[unsafe(naked)]
 pub extern "C" fn using_const_generics<const N: u64>(x: u64) -> u64 {
     const M: u64 = 42;
 
-    unsafe {
-        naked_asm!(
-            "xor rax, rax",
-            "add rax, rdi",
-            "add rax, {}",
-            "add rax, {}",
-            "ret",
-            const N,
-            const M,
-        )
-    }
+    naked_asm!(
+        "xor rax, rax",
+        "add rax, rdi",
+        "add rax, {}",
+        "add rax, {}",
+        "ret",
+        const N,
+        const M,
+    )
 }
 
 trait Invert {
@@ -60,16 +58,14 @@ impl Invert for i64 {
 // CHECK: call
 // CHECK: ret
 
-#[naked]
+#[unsafe(naked)]
 #[no_mangle]
 pub extern "C" fn generic_function<T: Invert>(x: i64) -> i64 {
-    unsafe {
-        naked_asm!(
-            "call {}",
-            "ret",
-            sym <T as Invert>::invert,
-        )
-    }
+    naked_asm!(
+        "call {}",
+        "ret",
+        sym <T as Invert>::invert,
+    )
 }
 
 #[derive(Copy, Clone)]
@@ -81,10 +77,10 @@ struct Foo(u64);
 // CHECK: mov rax, rdi
 
 impl Foo {
-    #[naked]
+    #[unsafe(naked)]
     #[no_mangle]
     extern "C" fn method(self) -> u64 {
-        unsafe { naked_asm!("mov rax, rdi", "ret") }
+        naked_asm!("mov rax, rdi", "ret")
     }
 }
 
@@ -97,10 +93,10 @@ trait Bar {
 }
 
 impl Bar for Foo {
-    #[naked]
+    #[unsafe(naked)]
     #[no_mangle]
     extern "C" fn trait_method(self) -> u64 {
-        unsafe { naked_asm!("mov rax, rdi", "ret") }
+        naked_asm!("mov rax, rdi", "ret")
     }
 }
 
@@ -109,7 +105,7 @@ impl Bar for Foo {
 // CHECK: lea rax, [rdi + rsi]
 
 // this previously ICE'd, see https://github.com/rust-lang/rust/issues/124375
-#[naked]
+#[unsafe(naked)]
 #[no_mangle]
 pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {
     naked_asm!("lea rax, [rdi + rsi]", "ret");
diff --git a/tests/codegen/naked-fn/instruction-set.rs b/tests/codegen/naked-fn/instruction-set.rs
index a7b4c22a59bfd..2ccd47d645858 100644
--- a/tests/codegen/naked-fn/instruction-set.rs
+++ b/tests/codegen/naked-fn/instruction-set.rs
@@ -20,8 +20,8 @@ use minicore::*;
 // arm-mode: .arm
 // thumb-mode: .thumb
 #[no_mangle]
-#[naked]
-unsafe extern "C" fn test_unspecified() {
+#[unsafe(naked)]
+extern "C" fn test_unspecified() {
     naked_asm!("bx lr");
 }
 
@@ -33,9 +33,9 @@ unsafe extern "C" fn test_unspecified() {
 // arm-mode: .arm
 // thumb-mode: .thumb
 #[no_mangle]
-#[naked]
+#[unsafe(naked)]
 #[instruction_set(arm::t32)]
-unsafe extern "C" fn test_thumb() {
+extern "C" fn test_thumb() {
     naked_asm!("bx lr");
 }
 
@@ -46,8 +46,8 @@ unsafe extern "C" fn test_thumb() {
 // arm-mode: .arm
 // thumb-mode: .thumb
 #[no_mangle]
-#[naked]
+#[unsafe(naked)]
 #[instruction_set(arm::a32)]
-unsafe extern "C" fn test_arm() {
+extern "C" fn test_arm() {
     naked_asm!("bx lr");
 }
diff --git a/tests/codegen/naked-fn/min-function-alignment.rs b/tests/codegen/naked-fn/min-function-alignment.rs
index 1330d796d397f..4a9142288248b 100644
--- a/tests/codegen/naked-fn/min-function-alignment.rs
+++ b/tests/codegen/naked-fn/min-function-alignment.rs
@@ -9,24 +9,24 @@
 //
 // CHECK: .balign 16
 #[no_mangle]
-#[naked]
-pub unsafe extern "C" fn naked_no_explicit_align() {
+#[unsafe(naked)]
+pub extern "C" fn naked_no_explicit_align() {
     core::arch::naked_asm!("ret")
 }
 
 // CHECK: .balign 16
 #[no_mangle]
 #[repr(align(8))]
-#[naked]
-pub unsafe extern "C" fn naked_lower_align() {
+#[unsafe(naked)]
+pub extern "C" fn naked_lower_align() {
     core::arch::naked_asm!("ret")
 }
 
 // CHECK: .balign 32
 #[no_mangle]
 #[repr(align(32))]
-#[naked]
-pub unsafe extern "C" fn naked_higher_align() {
+#[unsafe(naked)]
+pub extern "C" fn naked_higher_align() {
     core::arch::naked_asm!("ret")
 }
 
@@ -38,7 +38,7 @@ pub unsafe extern "C" fn naked_higher_align() {
 // CHECK: .balign 16
 #[no_mangle]
 #[cold]
-#[naked]
-pub unsafe extern "C" fn no_explicit_align_cold() {
+#[unsafe(naked)]
+pub extern "C" fn no_explicit_align_cold() {
     core::arch::naked_asm!("ret")
 }
diff --git a/tests/codegen/naked-fn/naked-functions.rs b/tests/codegen/naked-fn/naked-functions.rs
index 3fe795178b702..1bcdd6de373e5 100644
--- a/tests/codegen/naked-fn/naked-functions.rs
+++ b/tests/codegen/naked-fn/naked-functions.rs
@@ -60,8 +60,8 @@ use minicore::*;
 // linux,win: .att_syntax
 
 #[no_mangle]
-#[naked]
-pub unsafe extern "C" fn naked_empty() {
+#[unsafe(naked)]
+pub extern "C" fn naked_empty() {
     #[cfg(not(all(target_arch = "arm", target_feature = "thumb-mode")))]
     naked_asm!("ret");
 
@@ -114,8 +114,8 @@ pub unsafe extern "C" fn naked_empty() {
 // linux,win: .att_syntax
 
 #[no_mangle]
-#[naked]
-pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {
+#[unsafe(naked)]
+pub extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {
     #[cfg(any(target_os = "windows", target_os = "linux"))]
     {
         naked_asm!("lea rax, [rdi + rsi]", "ret")
@@ -138,9 +138,9 @@ pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize
 // thumb:            .pushsection .text.some_different_name,\22ax\22, %progbits
 // CHECK-LABEL: test_link_section:
 #[no_mangle]
-#[naked]
+#[unsafe(naked)]
 #[link_section = ".text.some_different_name"]
-pub unsafe extern "C" fn test_link_section() {
+pub extern "C" fn test_link_section() {
     #[cfg(not(all(target_arch = "arm", target_feature = "thumb-mode")))]
     naked_asm!("ret");
 
@@ -159,7 +159,7 @@ pub unsafe extern "C" fn test_link_section() {
 // win_i686-LABEL: @fastcall_cc@4:
 #[cfg(target_os = "windows")]
 #[no_mangle]
-#[naked]
-pub unsafe extern "fastcall" fn fastcall_cc(x: i32) -> i32 {
+#[unsafe(naked)]
+pub extern "fastcall" fn fastcall_cc(x: i32) -> i32 {
     naked_asm!("ret");
 }
diff --git a/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs b/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs
index f98a2036544c3..ae75519525363 100644
--- a/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs
+++ b/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs
@@ -26,9 +26,9 @@ extern "C" fn private_vanilla() -> u32 {
     42
 }
 
-#[naked]
+#[unsafe(naked)]
 extern "C" fn private_naked() -> u32 {
-    unsafe { naked_asm!("mov rax, 42", "ret") }
+    naked_asm!("mov rax, 42", "ret")
 }
 
 #[no_mangle]
@@ -36,19 +36,19 @@ pub extern "C" fn public_vanilla() -> u32 {
     42
 }
 
-#[naked]
+#[unsafe(naked)]
 #[no_mangle]
 pub extern "C" fn public_naked_nongeneric() -> u32 {
-    unsafe { naked_asm!("mov rax, 42", "ret") }
+    naked_asm!("mov rax, 42", "ret")
 }
 
 pub extern "C" fn public_vanilla_generic<T: TraitWithConst>() -> u32 {
     T::COUNT
 }
 
-#[naked]
+#[unsafe(naked)]
 pub extern "C" fn public_naked_generic<T: TraitWithConst>() -> u32 {
-    unsafe { naked_asm!("mov rax, {}", "ret", const T::COUNT) }
+    naked_asm!("mov rax, {}", "ret", const T::COUNT)
 }
 
 #[linkage = "external"]
@@ -56,10 +56,10 @@ extern "C" fn vanilla_external_linkage() -> u32 {
     42
 }
 
-#[naked]
+#[unsafe(naked)]
 #[linkage = "external"]
 extern "C" fn naked_external_linkage() -> u32 {
-    unsafe { naked_asm!("mov rax, 42", "ret") }
+    naked_asm!("mov rax, 42", "ret")
 }
 
 #[cfg(not(windows))]
@@ -68,11 +68,11 @@ extern "C" fn vanilla_weak_linkage() -> u32 {
     42
 }
 
-#[naked]
+#[unsafe(naked)]
 #[cfg(not(windows))]
 #[linkage = "weak"]
 extern "C" fn naked_weak_linkage() -> u32 {
-    unsafe { naked_asm!("mov rax, 42", "ret") }
+    naked_asm!("mov rax, 42", "ret")
 }
 
 // functions that are declared in an `extern "C"` block are currently not exported
diff --git a/tests/ui/asm/naked-asm-outside-naked-fn.rs b/tests/ui/asm/naked-asm-outside-naked-fn.rs
index 1696008f3397d..a7680cc63ae03 100644
--- a/tests/ui/asm/naked-asm-outside-naked-fn.rs
+++ b/tests/ui/asm/naked-asm-outside-naked-fn.rs
@@ -12,24 +12,24 @@ fn main() {
     test1();
 }
 
-#[naked]
+#[unsafe(naked)]
 extern "C" fn test1() {
-    unsafe { naked_asm!("") }
+    naked_asm!("")
 }
 
 extern "C" fn test2() {
-    unsafe { naked_asm!("") }
-    //~^ ERROR the `naked_asm!` macro can only be used in functions marked with `#[naked]`
+    naked_asm!("")
+    //~^ ERROR the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]`
 }
 
 extern "C" fn test3() {
-    unsafe { (|| naked_asm!(""))() }
-    //~^ ERROR the `naked_asm!` macro can only be used in functions marked with `#[naked]`
+    (|| naked_asm!(""))()
+    //~^ ERROR the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]`
 }
 
 fn test4() {
     async move {
-        unsafe {  naked_asm!("") } ;
-        //~^ ERROR the `naked_asm!` macro can only be used in functions marked with `#[naked]`
+        naked_asm!("");
+        //~^ ERROR the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]`
     };
 }
diff --git a/tests/ui/asm/naked-asm-outside-naked-fn.stderr b/tests/ui/asm/naked-asm-outside-naked-fn.stderr
index 6e91359669ca2..85a50a49fecfc 100644
--- a/tests/ui/asm/naked-asm-outside-naked-fn.stderr
+++ b/tests/ui/asm/naked-asm-outside-naked-fn.stderr
@@ -1,20 +1,20 @@
-error: the `naked_asm!` macro can only be used in functions marked with `#[naked]`
-  --> $DIR/naked-asm-outside-naked-fn.rs:21:14
+error: the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]`
+  --> $DIR/naked-asm-outside-naked-fn.rs:21:5
    |
-LL |     unsafe { naked_asm!("") }
-   |              ^^^^^^^^^^^^^^
+LL |     naked_asm!("")
+   |     ^^^^^^^^^^^^^^
 
-error: the `naked_asm!` macro can only be used in functions marked with `#[naked]`
-  --> $DIR/naked-asm-outside-naked-fn.rs:26:18
+error: the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]`
+  --> $DIR/naked-asm-outside-naked-fn.rs:26:9
    |
-LL |     unsafe { (|| naked_asm!(""))() }
-   |                  ^^^^^^^^^^^^^^
+LL |     (|| naked_asm!(""))()
+   |         ^^^^^^^^^^^^^^
 
-error: the `naked_asm!` macro can only be used in functions marked with `#[naked]`
-  --> $DIR/naked-asm-outside-naked-fn.rs:32:19
+error: the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]`
+  --> $DIR/naked-asm-outside-naked-fn.rs:32:9
    |
-LL |         unsafe {  naked_asm!("") } ;
-   |                   ^^^^^^^^^^^^^^
+LL |         naked_asm!("");
+   |         ^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/asm/naked-functions-ffi.rs b/tests/ui/asm/naked-functions-ffi.rs
index b78d1e6a0d1c6..8fd0da01d72a7 100644
--- a/tests/ui/asm/naked-functions-ffi.rs
+++ b/tests/ui/asm/naked-functions-ffi.rs
@@ -5,11 +5,9 @@
 
 use std::arch::naked_asm;
 
-#[naked]
+#[unsafe(naked)]
 pub extern "C" fn naked(p: char) -> u128 {
     //~^ WARN uses type `char`
     //~| WARN uses type `u128`
-    unsafe {
-        naked_asm!("");
-    }
+    naked_asm!("")
 }
diff --git a/tests/ui/asm/naked-functions-inline.rs b/tests/ui/asm/naked-functions-inline.rs
index 74049e8ecbc7c..261401be64517 100644
--- a/tests/ui/asm/naked-functions-inline.rs
+++ b/tests/ui/asm/naked-functions-inline.rs
@@ -4,35 +4,35 @@
 
 use std::arch::naked_asm;
 
-#[naked]
-pub unsafe extern "C" fn inline_none() {
+#[unsafe(naked)]
+pub extern "C" fn inline_none() {
     naked_asm!("");
 }
 
-#[naked]
+#[unsafe(naked)]
 #[inline]
 //~^ ERROR [E0736]
-pub unsafe extern "C" fn inline_hint() {
+pub extern "C" fn inline_hint() {
     naked_asm!("");
 }
 
-#[naked]
+#[unsafe(naked)]
 #[inline(always)]
 //~^ ERROR [E0736]
-pub unsafe extern "C" fn inline_always() {
+pub extern "C" fn inline_always() {
     naked_asm!("");
 }
 
-#[naked]
+#[unsafe(naked)]
 #[inline(never)]
 //~^ ERROR [E0736]
-pub unsafe extern "C" fn inline_never() {
+pub extern "C" fn inline_never() {
     naked_asm!("");
 }
 
-#[naked]
+#[unsafe(naked)]
 #[cfg_attr(all(), inline(never))]
 //~^ ERROR [E0736]
-pub unsafe extern "C" fn conditional_inline_never() {
+pub extern "C" fn conditional_inline_never() {
     naked_asm!("");
 }
diff --git a/tests/ui/asm/naked-functions-inline.stderr b/tests/ui/asm/naked-functions-inline.stderr
index 84a688f6f5382..6df5b08ae8534 100644
--- a/tests/ui/asm/naked-functions-inline.stderr
+++ b/tests/ui/asm/naked-functions-inline.stderr
@@ -1,34 +1,34 @@
-error[E0736]: attribute incompatible with `#[naked]`
+error[E0736]: attribute incompatible with `#[unsafe(naked)]`
   --> $DIR/naked-functions-inline.rs:13:1
    |
-LL | #[naked]
-   | -------- function marked with `#[naked]` here
+LL | #[unsafe(naked)]
+   | ---------------- function marked with `#[unsafe(naked)]` here
 LL | #[inline]
-   | ^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
+   | ^^^^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]`
 
-error[E0736]: attribute incompatible with `#[naked]`
+error[E0736]: attribute incompatible with `#[unsafe(naked)]`
   --> $DIR/naked-functions-inline.rs:20:1
    |
-LL | #[naked]
-   | -------- function marked with `#[naked]` here
+LL | #[unsafe(naked)]
+   | ---------------- function marked with `#[unsafe(naked)]` here
 LL | #[inline(always)]
-   | ^^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
+   | ^^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]`
 
-error[E0736]: attribute incompatible with `#[naked]`
+error[E0736]: attribute incompatible with `#[unsafe(naked)]`
   --> $DIR/naked-functions-inline.rs:27:1
    |
-LL | #[naked]
-   | -------- function marked with `#[naked]` here
+LL | #[unsafe(naked)]
+   | ---------------- function marked with `#[unsafe(naked)]` here
 LL | #[inline(never)]
-   | ^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
+   | ^^^^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]`
 
-error[E0736]: attribute incompatible with `#[naked]`
+error[E0736]: attribute incompatible with `#[unsafe(naked)]`
   --> $DIR/naked-functions-inline.rs:34:19
    |
-LL | #[naked]
-   | -------- function marked with `#[naked]` here
+LL | #[unsafe(naked)]
+   | ---------------- function marked with `#[unsafe(naked)]` here
 LL | #[cfg_attr(all(), inline(never))]
-   |                   ^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[naked]`
+   |                   ^^^^^^^^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]`
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/asm/naked-functions-instruction-set.rs b/tests/ui/asm/naked-functions-instruction-set.rs
index 28241badf5f87..6fd34b035edd0 100644
--- a/tests/ui/asm/naked-functions-instruction-set.rs
+++ b/tests/ui/asm/naked-functions-instruction-set.rs
@@ -12,15 +12,15 @@ extern crate minicore;
 use minicore::*;
 
 #[no_mangle]
-#[naked]
+#[unsafe(naked)]
 #[instruction_set(arm::t32)]
-unsafe extern "C" fn test_thumb() {
+extern "C" fn test_thumb() {
     naked_asm!("bx lr");
 }
 
 #[no_mangle]
-#[naked]
+#[unsafe(naked)]
 #[instruction_set(arm::a32)]
-unsafe extern "C" fn test_arm() {
+extern "C" fn test_arm() {
     naked_asm!("bx lr");
 }
diff --git a/tests/ui/asm/naked-functions-rustic-abi.rs b/tests/ui/asm/naked-functions-rustic-abi.rs
index b654d38ccc1a6..99b8d2e19fe40 100644
--- a/tests/ui/asm/naked-functions-rustic-abi.rs
+++ b/tests/ui/asm/naked-functions-rustic-abi.rs
@@ -11,17 +11,17 @@
 
 use std::arch::{asm, naked_asm};
 
-#[naked]
-pub unsafe fn rust_implicit() {
+#[unsafe(naked)]
+pub fn rust_implicit() {
     naked_asm!("ret");
 }
 
-#[naked]
-pub unsafe extern "Rust" fn rust_explicit() {
+#[unsafe(naked)]
+pub extern "Rust" fn rust_explicit() {
     naked_asm!("ret");
 }
 
-#[naked]
-pub unsafe extern "rust-cold" fn rust_cold() {
+#[unsafe(naked)]
+pub extern "rust-cold" fn rust_cold() {
     naked_asm!("ret");
 }
diff --git a/tests/ui/asm/naked-functions-target-feature.rs b/tests/ui/asm/naked-functions-target-feature.rs
index afe1a38914720..d8dc2104c76e1 100644
--- a/tests/ui/asm/naked-functions-target-feature.rs
+++ b/tests/ui/asm/naked-functions-target-feature.rs
@@ -8,14 +8,14 @@ use std::arch::{asm, naked_asm};
 
 #[cfg(target_arch = "x86_64")]
 #[target_feature(enable = "sse2")]
-#[naked]
-pub unsafe extern "C" fn compatible_target_feature() {
-    naked_asm!("");
+#[unsafe(naked)]
+pub extern "C" fn compatible_target_feature() {
+    naked_asm!("ret");
 }
 
 #[cfg(target_arch = "aarch64")]
 #[target_feature(enable = "neon")]
-#[naked]
-pub unsafe extern "C" fn compatible_target_feature() {
-    naked_asm!("");
+#[unsafe(naked)]
+pub extern "C" fn compatible_target_feature() {
+    naked_asm!("ret");
 }
diff --git a/tests/ui/asm/naked-functions-testattrs.rs b/tests/ui/asm/naked-functions-testattrs.rs
index ad31876a77a59..c8539e8064088 100644
--- a/tests/ui/asm/naked-functions-testattrs.rs
+++ b/tests/ui/asm/naked-functions-testattrs.rs
@@ -8,31 +8,31 @@
 use std::arch::naked_asm;
 
 #[test]
-#[naked]
+#[unsafe(naked)]
 //~^ ERROR [E0736]
 extern "C" fn test_naked() {
-    unsafe { naked_asm!("") };
+    naked_asm!("")
 }
 
 #[should_panic]
 #[test]
-#[naked]
+#[unsafe(naked)]
 //~^ ERROR [E0736]
 extern "C" fn test_naked_should_panic() {
-    unsafe { naked_asm!("") };
+    naked_asm!("")
 }
 
 #[ignore]
 #[test]
-#[naked]
+#[unsafe(naked)]
 //~^ ERROR [E0736]
 extern "C" fn test_naked_ignore() {
-    unsafe { naked_asm!("") };
+    naked_asm!("")
 }
 
 #[bench]
-#[naked]
+#[unsafe(naked)]
 //~^ ERROR [E0736]
 extern "C" fn bench_naked() {
-    unsafe { naked_asm!("") };
+    naked_asm!("")
 }
diff --git a/tests/ui/asm/naked-functions-testattrs.stderr b/tests/ui/asm/naked-functions-testattrs.stderr
index 0f0bb91b95413..ad2041ec118b9 100644
--- a/tests/ui/asm/naked-functions-testattrs.stderr
+++ b/tests/ui/asm/naked-functions-testattrs.stderr
@@ -1,34 +1,34 @@
-error[E0736]: cannot use `#[naked]` with testing attributes
+error[E0736]: cannot use `#[unsafe(naked)]` with testing attributes
   --> $DIR/naked-functions-testattrs.rs:11:1
    |
 LL | #[test]
    | ------- function marked with testing attribute here
-LL | #[naked]
-   | ^^^^^^^^ `#[naked]` is incompatible with testing attributes
+LL | #[unsafe(naked)]
+   | ^^^^^^^^^^^^^^^^ `#[unsafe(naked)]` is incompatible with testing attributes
 
-error[E0736]: cannot use `#[naked]` with testing attributes
+error[E0736]: cannot use `#[unsafe(naked)]` with testing attributes
   --> $DIR/naked-functions-testattrs.rs:19:1
    |
 LL | #[test]
    | ------- function marked with testing attribute here
-LL | #[naked]
-   | ^^^^^^^^ `#[naked]` is incompatible with testing attributes
+LL | #[unsafe(naked)]
+   | ^^^^^^^^^^^^^^^^ `#[unsafe(naked)]` is incompatible with testing attributes
 
-error[E0736]: cannot use `#[naked]` with testing attributes
+error[E0736]: cannot use `#[unsafe(naked)]` with testing attributes
   --> $DIR/naked-functions-testattrs.rs:27:1
    |
 LL | #[test]
    | ------- function marked with testing attribute here
-LL | #[naked]
-   | ^^^^^^^^ `#[naked]` is incompatible with testing attributes
+LL | #[unsafe(naked)]
+   | ^^^^^^^^^^^^^^^^ `#[unsafe(naked)]` is incompatible with testing attributes
 
-error[E0736]: cannot use `#[naked]` with testing attributes
+error[E0736]: cannot use `#[unsafe(naked)]` with testing attributes
   --> $DIR/naked-functions-testattrs.rs:34:1
    |
 LL | #[bench]
    | -------- function marked with testing attribute here
-LL | #[naked]
-   | ^^^^^^^^ `#[naked]` is incompatible with testing attributes
+LL | #[unsafe(naked)]
+   | ^^^^^^^^^^^^^^^^ `#[unsafe(naked)]` is incompatible with testing attributes
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/asm/naked-functions-unused.rs b/tests/ui/asm/naked-functions-unused.rs
index c27037819a44f..67c05984be71c 100644
--- a/tests/ui/asm/naked-functions-unused.rs
+++ b/tests/ui/asm/naked-functions-unused.rs
@@ -64,44 +64,34 @@ pub mod normal {
 pub mod naked {
     use std::arch::naked_asm;
 
-    #[naked]
+    #[unsafe(naked)]
     pub extern "C" fn function(a: usize, b: usize) -> usize {
-        unsafe {
-            naked_asm!("");
-        }
+        naked_asm!("")
     }
 
     pub struct Naked;
 
     impl Naked {
-        #[naked]
+        #[unsafe(naked)]
         pub extern "C" fn associated(a: usize, b: usize) -> usize {
-            unsafe {
-                naked_asm!("");
-            }
+            naked_asm!("")
         }
 
-        #[naked]
+        #[unsafe(naked)]
         pub extern "C" fn method(&self, a: usize, b: usize) -> usize {
-            unsafe {
-                naked_asm!("");
-            }
+            naked_asm!("")
         }
     }
 
     impl super::Trait for Naked {
-        #[naked]
+        #[unsafe(naked)]
         extern "C" fn trait_associated(a: usize, b: usize) -> usize {
-            unsafe {
-                naked_asm!("");
-            }
+            naked_asm!("")
         }
 
-        #[naked]
+        #[unsafe(naked)]
         extern "C" fn trait_method(&self, a: usize, b: usize) -> usize {
-            unsafe {
-                naked_asm!("");
-            }
+            naked_asm!("")
         }
     }
 }
diff --git a/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs
index 8ba0eecb7b5c7..b433c1b5389c4 100644
--- a/tests/ui/asm/naked-functions.rs
+++ b/tests/ui/asm/naked-functions.rs
@@ -9,8 +9,8 @@
 use std::arch::{asm, naked_asm};
 
 #[unsafe(naked)]
-pub unsafe extern "C" fn inline_asm_macro() {
-    asm!("", options(raw));
+pub extern "C" fn inline_asm_macro() {
+    unsafe { asm!("", options(raw)) };
     //~^ERROR the `asm!` macro is not allowed in naked functions
 }
 
@@ -21,7 +21,7 @@ pub struct P {
 }
 
 #[unsafe(naked)]
-pub unsafe extern "C" fn patterns(
+pub extern "C" fn patterns(
     mut a: u32,
     //~^ ERROR patterns not allowed in naked function parameters
     &b: &i32,
@@ -35,7 +35,7 @@ pub unsafe extern "C" fn patterns(
 }
 
 #[unsafe(naked)]
-pub unsafe extern "C" fn inc(a: u32) -> u32 {
+pub extern "C" fn inc(a: u32) -> u32 {
     //~^ ERROR naked functions must contain a single `naked_asm!` invocation
     a + 1
     //~^ ERROR referencing function parameters is not allowed in naked functions
@@ -43,19 +43,19 @@ pub unsafe extern "C" fn inc(a: u32) -> u32 {
 
 #[unsafe(naked)]
 #[allow(asm_sub_register)]
-pub unsafe extern "C" fn inc_asm(a: u32) -> u32 {
+pub extern "C" fn inc_asm(a: u32) -> u32 {
     naked_asm!("/* {0} */", in(reg) a)
     //~^ ERROR the `in` operand cannot be used with `naked_asm!`
 }
 
 #[unsafe(naked)]
-pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
+pub extern "C" fn inc_closure(a: u32) -> u32 {
     //~^ ERROR naked functions must contain a single `naked_asm!` invocation
     (|| a + 1)()
 }
 
 #[unsafe(naked)]
-pub unsafe extern "C" fn unsupported_operands() {
+pub extern "C" fn unsupported_operands() {
     //~^ ERROR naked functions must contain a single `naked_asm!` invocation
     let mut a = 0usize;
     let mut b = 0usize;
@@ -84,11 +84,10 @@ pub extern "C" fn missing_assembly() {
 #[unsafe(naked)]
 pub extern "C" fn too_many_asm_blocks() {
     //~^ ERROR naked functions must contain a single `naked_asm!` invocation
-    unsafe {
-        naked_asm!("", options(noreturn));
-        //~^ ERROR the `noreturn` option cannot be used with `naked_asm!`
-        naked_asm!("");
-    }
+
+    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 {
@@ -124,49 +123,44 @@ unsafe extern "C" fn invalid_may_unwind() {
 
 #[unsafe(naked)]
 pub extern "C" fn valid_a<T>() -> T {
-    unsafe {
-        naked_asm!("");
-    }
+    naked_asm!("");
 }
 
 #[unsafe(naked)]
 pub extern "C" fn valid_b() {
-    unsafe {
+    {
         {
-            {
-                naked_asm!("");
-            };
+            naked_asm!("");
         };
-    }
+    };
 }
 
 #[unsafe(naked)]
-pub unsafe extern "C" fn valid_c() {
+pub extern "C" fn valid_c() {
     naked_asm!("");
 }
 
 #[cfg(target_arch = "x86_64")]
 #[unsafe(naked)]
-pub unsafe extern "C" fn valid_att_syntax() {
+pub extern "C" fn valid_att_syntax() {
     naked_asm!("", options(att_syntax));
 }
 
 #[unsafe(naked)]
-#[unsafe(naked)]
-pub unsafe extern "C" fn allow_compile_error(a: u32) -> u32 {
+pub extern "C" fn allow_compile_error(a: u32) -> u32 {
     compile_error!("this is a user specified error")
     //~^ ERROR this is a user specified error
 }
 
 #[unsafe(naked)]
-pub unsafe extern "C" fn allow_compile_error_and_asm(a: u32) -> u32 {
+pub 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!("")
 }
 
 #[unsafe(naked)]
-pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 {
+pub extern "C" fn invalid_asm_syntax(a: u32) -> u32 {
     naked_asm!(invalid_syntax)
     //~^ ERROR asm template must be a string literal
 }
@@ -174,7 +168,7 @@ pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 {
 #[cfg(target_arch = "x86_64")]
 #[cfg_attr(target_pointer_width = "64", no_mangle)]
 #[unsafe(naked)]
-pub unsafe extern "C" fn compatible_cfg_attributes() {
+pub extern "C" fn compatible_cfg_attributes() {
     naked_asm!("", options(att_syntax));
 }
 
@@ -183,20 +177,20 @@ pub unsafe extern "C" fn compatible_cfg_attributes() {
 #[deny(dead_code)]
 #[forbid(dead_code)]
 #[unsafe(naked)]
-pub unsafe extern "C" fn compatible_diagnostic_attributes() {
+pub extern "C" fn compatible_diagnostic_attributes() {
     naked_asm!("", options(raw));
 }
 
 #[deprecated = "test"]
 #[unsafe(naked)]
-pub unsafe extern "C" fn compatible_deprecated_attributes() {
+pub extern "C" fn compatible_deprecated_attributes() {
     naked_asm!("", options(raw));
 }
 
 #[cfg(target_arch = "x86_64")]
 #[must_use]
 #[unsafe(naked)]
-pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
+pub extern "C" fn compatible_must_use_attributes() -> u64 {
     naked_asm!(
         "
         mov rax, 42
@@ -208,13 +202,13 @@ pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
 #[export_name = "exported_function_name"]
 #[link_section = ".custom_section"]
 #[unsafe(naked)]
-pub unsafe extern "C" fn compatible_ffi_attributes_1() {
+pub extern "C" fn compatible_ffi_attributes_1() {
     naked_asm!("", options(raw));
 }
 
 #[cold]
 #[unsafe(naked)]
-pub unsafe extern "C" fn compatible_codegen_attributes() {
+pub extern "C" fn compatible_codegen_attributes() {
     naked_asm!("", options(raw));
 }
 
@@ -223,12 +217,12 @@ pub unsafe extern "C" fn compatible_codegen_attributes() {
 // a normal comment
 #[doc(alias = "ADocAlias")]
 #[unsafe(naked)]
-pub unsafe extern "C" fn compatible_doc_attributes() {
+pub extern "C" fn compatible_doc_attributes() {
     naked_asm!("", options(raw));
 }
 
 #[linkage = "external"]
 #[unsafe(naked)]
-pub unsafe extern "C" fn compatible_linkage() {
+pub extern "C" fn compatible_linkage() {
     naked_asm!("", options(raw));
 }
diff --git a/tests/ui/asm/naked-functions.stderr b/tests/ui/asm/naked-functions.stderr
index 0a55bb9cd8370..2b67c3aecd73c 100644
--- a/tests/ui/asm/naked-functions.stderr
+++ b/tests/ui/asm/naked-functions.stderr
@@ -11,70 +11,70 @@ 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
+  --> $DIR/naked-functions.rs:88:28
    |
-LL |         naked_asm!("", options(noreturn));
-   |                                ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly
+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:106:28
+  --> $DIR/naked-functions.rs:105:28
    |
 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:106:35
+  --> $DIR/naked-functions.rs:105:35
    |
 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:113:28
+  --> $DIR/naked-functions.rs:112: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:113:38
+  --> $DIR/naked-functions.rs:112: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:113:56
+  --> $DIR/naked-functions.rs:112: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:121:28
+  --> $DIR/naked-functions.rs:120:28
    |
 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:157:5
+  --> $DIR/naked-functions.rs:151:5
    |
 LL |     compile_error!("this is a user specified error")
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this is a user specified error
-  --> $DIR/naked-functions.rs:163:5
+  --> $DIR/naked-functions.rs:157:5
    |
 LL |     compile_error!("this is a user specified error");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: asm template must be a string literal
-  --> $DIR/naked-functions.rs:170:16
+  --> $DIR/naked-functions.rs:164:16
    |
 LL |     naked_asm!(invalid_syntax)
    |                ^^^^^^^^^^^^^^
 
 error[E0787]: the `asm!` macro is not allowed in naked functions
-  --> $DIR/naked-functions.rs:13:5
+  --> $DIR/naked-functions.rs:13:14
    |
-LL |     asm!("", options(raw));
-   |     ^^^^^^^^^^^^^^^^^^^^^^ consider using the `naked_asm!` macro instead
+LL |     unsafe { asm!("", options(raw)) };
+   |              ^^^^^^^^^^^^^^^^^^^^^^ consider using the `naked_asm!` macro instead
 
 error: patterns not allowed in naked function parameters
   --> $DIR/naked-functions.rs:25:5
@@ -111,8 +111,8 @@ LL |     a + 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 | pub extern "C" fn inc(a: u32) -> u32 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     a + 1
    |     ----- not allowed in naked functions
@@ -120,8 +120,8 @@ LL |     a + 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 | pub extern "C" fn inc_closure(a: u32) -> u32 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     (|| a + 1)()
    |     ------------ not allowed in naked functions
@@ -129,8 +129,8 @@ LL |     (|| a + 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 | pub extern "C" fn unsupported_operands() {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     let mut a = 0usize;
    |     ------------------- not allowed in naked functions
@@ -155,11 +155,11 @@ error[E0787]: naked functions must contain a single `naked_asm!` invocation
 LL | pub extern "C" fn too_many_asm_blocks() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 ...
-LL |         naked_asm!("");
-   |         -------------- multiple `naked_asm!` invocations are not allowed in naked functions
+LL |     naked_asm!("");
+   |     -------------- multiple `naked_asm!` invocations are not allowed in naked functions
 
 error: referencing function parameters is not allowed in naked functions
-  --> $DIR/naked-functions.rs:98:11
+  --> $DIR/naked-functions.rs:97:11
    |
 LL |         *&y
    |           ^
@@ -167,7 +167,7 @@ LL |         *&y
    = help: follow the calling convention in asm block to use parameters
 
 error[E0787]: naked functions must contain a single `naked_asm!` invocation
-  --> $DIR/naked-functions.rs:96:5
+  --> $DIR/naked-functions.rs:95:5
    |
 LL |     pub extern "C" fn inner(y: usize) -> usize {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/asm/naked-invalid-attr.rs b/tests/ui/asm/naked-invalid-attr.rs
index 4053c58fb5136..6c5fdbe74d82a 100644
--- a/tests/ui/asm/naked-invalid-attr.rs
+++ b/tests/ui/asm/naked-invalid-attr.rs
@@ -1,17 +1,17 @@
-// Checks that #[naked] attribute can be placed on function definitions only.
+// Checks that #[unsafe(naked)] attribute can be placed on function definitions only.
 //
 //@ needs-asm-support
 #![feature(naked_functions)]
-#![naked] //~ ERROR should be applied to a function definition
+#![unsafe(naked)] //~ ERROR should be applied to a function definition
 
 use std::arch::naked_asm;
 
 extern "C" {
-    #[naked] //~ ERROR should be applied to a function definition
+    #[unsafe(naked)] //~ ERROR should be applied to a function definition
     fn f();
 }
 
-#[naked] //~ ERROR should be applied to a function definition
+#[unsafe(naked)] //~ ERROR should be applied to a function definition
 #[repr(C)]
 struct S {
     a: u32,
@@ -19,35 +19,35 @@ struct S {
 }
 
 trait Invoke {
-    #[naked] //~ ERROR should be applied to a function definition
+    #[unsafe(naked)] //~ ERROR should be applied to a function definition
     extern "C" fn invoke(&self);
 }
 
 impl Invoke for S {
-    #[naked]
+    #[unsafe(naked)]
     extern "C" fn invoke(&self) {
-        unsafe { naked_asm!("") }
+        naked_asm!("")
     }
 }
 
-#[naked]
+#[unsafe(naked)]
 extern "C" fn ok() {
-    unsafe { naked_asm!("") }
+    naked_asm!("")
 }
 
 impl S {
-    #[naked]
+    #[unsafe(naked)]
     extern "C" fn g() {
-        unsafe { naked_asm!("") }
+        naked_asm!("")
     }
 
-    #[naked]
+    #[unsafe(naked)]
     extern "C" fn h(&self) {
-        unsafe { naked_asm!("") }
+        naked_asm!("")
     }
 }
 
 fn main() {
-    #[naked] //~ ERROR should be applied to a function definition
+    #[unsafe(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 640f9d9510d15..6e2746b568437 100644
--- a/tests/ui/asm/naked-invalid-attr.stderr
+++ b/tests/ui/asm/naked-invalid-attr.stderr
@@ -1,8 +1,8 @@
 error: attribute should be applied to a function definition
   --> $DIR/naked-invalid-attr.rs:14:1
    |
-LL |   #[naked]
-   |   ^^^^^^^^
+LL |   #[unsafe(naked)]
+   |   ^^^^^^^^^^^^^^^^
 LL |   #[repr(C)]
 LL | / struct S {
 LL | |     a: u32,
@@ -13,32 +13,32 @@ LL | | }
 error: attribute should be applied to a function definition
   --> $DIR/naked-invalid-attr.rs:51:5
    |
-LL |     #[naked]
-   |     ^^^^^^^^
+LL |     #[unsafe(naked)]
+   |     ^^^^^^^^^^^^^^^^
 LL |     || {};
    |     ----- not a function definition
 
 error: attribute should be applied to a function definition
   --> $DIR/naked-invalid-attr.rs:22:5
    |
-LL |     #[naked]
-   |     ^^^^^^^^
+LL |     #[unsafe(naked)]
+   |     ^^^^^^^^^^^^^^^^
 LL |     extern "C" fn invoke(&self);
    |     ---------------------------- not a function definition
 
 error: attribute should be applied to a function definition
   --> $DIR/naked-invalid-attr.rs:10:5
    |
-LL |     #[naked]
-   |     ^^^^^^^^
+LL |     #[unsafe(naked)]
+   |     ^^^^^^^^^^^^^^^^
 LL |     fn f();
    |     ------- not a function definition
 
 error: attribute should be applied to a function definition
   --> $DIR/naked-invalid-attr.rs:5:1
    |
-LL | #![naked]
-   | ^^^^^^^^^ cannot be applied to crates
+LL | #![unsafe(naked)]
+   | ^^^^^^^^^^^^^^^^^ cannot be applied to crates
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/asm/naked-with-invalid-repr-attr.rs b/tests/ui/asm/naked-with-invalid-repr-attr.rs
index 18b9c1014c3fa..c9f335ea9506a 100644
--- a/tests/ui/asm/naked-with-invalid-repr-attr.rs
+++ b/tests/ui/asm/naked-with-invalid-repr-attr.rs
@@ -6,43 +6,43 @@ use std::arch::naked_asm;
 
 #[repr(C)]
 //~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
-#[naked]
+#[unsafe(naked)]
 extern "C" fn example1() {
     //~^ NOTE not a struct, enum, or union
-    unsafe { naked_asm!("") }
+    naked_asm!("")
 }
 
 #[repr(transparent)]
 //~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
-#[naked]
+#[unsafe(naked)]
 extern "C" fn example2() {
     //~^ NOTE not a struct, enum, or union
-    unsafe { naked_asm!("") }
+    naked_asm!("")
 }
 
 #[repr(align(16), C)]
 //~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
-#[naked]
+#[unsafe(naked)]
 extern "C" fn example3() {
     //~^ NOTE not a struct, enum, or union
-    unsafe { naked_asm!("") }
+    naked_asm!("")
 }
 
 // note: two errors because of packed and C
 #[repr(C, packed)]
 //~^ ERROR attribute should be applied to a struct or union [E0517]
 //~| ERROR attribute should be applied to a struct, enum, or union [E0517]
-#[naked]
+#[unsafe(naked)]
 extern "C" fn example4() {
     //~^ NOTE not a struct, enum, or union
     //~| NOTE not a struct or union
-    unsafe { naked_asm!("") }
+    naked_asm!("")
 }
 
 #[repr(u8)]
 //~^ ERROR attribute should be applied to an enum [E0517]
-#[naked]
+#[unsafe(naked)]
 extern "C" fn example5() {
     //~^ NOTE not an enum
-    unsafe { naked_asm!("") }
+    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 8248a8c165791..219e32473beaa 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 { naked_asm!("") }
+LL | |     naked_asm!("")
 LL | | }
    | |_- not a struct, enum, or union
 
@@ -18,7 +18,7 @@ LL |   #[repr(transparent)]
 ...
 LL | / extern "C" fn example2() {
 LL | |
-LL | |     unsafe { naked_asm!("") }
+LL | |     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 { naked_asm!("") }
+LL | |     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 { naked_asm!("") }
+LL | |     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 { naked_asm!("") }
+LL | |     naked_asm!("")
 LL | | }
    | |_- not a struct or union
 
@@ -68,7 +68,7 @@ LL |   #[repr(u8)]
 ...
 LL | / extern "C" fn example5() {
 LL | |
-LL | |     unsafe { naked_asm!("") }
+LL | |     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 77831e679ed42..d5c194452d75b 100644
--- a/tests/ui/asm/named-asm-labels.rs
+++ b/tests/ui/asm/named-asm-labels.rs
@@ -175,9 +175,9 @@ fn main() {
 
 // Trigger on naked fns too, even though they can't be inlined, reusing a
 // label or LTO can cause labels to break
-#[naked]
+#[unsafe(naked)]
 pub extern "C" fn foo() -> i32 {
-    unsafe { naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1) }
+    naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1)
     //~^ ERROR avoid using named labels
 }
 
@@ -188,21 +188,21 @@ pub extern "C" fn bar() {
     //~^ ERROR avoid using named labels
 }
 
-#[naked]
+#[unsafe(naked)]
 pub extern "C" fn aaa() {
     fn _local() {}
 
-    unsafe { naked_asm!(".Laaa: nop; ret;") } //~ ERROR avoid using named labels
+    naked_asm!(".Laaa: nop; ret;") //~ ERROR avoid using named labels
 }
 
 pub fn normal() {
     fn _local1() {}
 
-    #[naked]
+    #[unsafe(naked)]
     pub extern "C" fn bbb() {
         fn _very_local() {}
 
-        unsafe { naked_asm!(".Lbbb: nop; ret;") } //~ ERROR avoid using named labels
+        naked_asm!(".Lbbb: nop; ret;") //~ ERROR avoid using named labels
     }
 
     fn _local2() {}
@@ -219,8 +219,8 @@ fn closures() {
     };
 
     || {
-        #[naked]
-        unsafe extern "C" fn _nested() {
+        #[unsafe(naked)]
+        extern "C" fn _nested() {
             naked_asm!("ret;");
         }
 
diff --git a/tests/ui/asm/named-asm-labels.stderr b/tests/ui/asm/named-asm-labels.stderr
index 44ce358c62bdb..0120d4948d51c 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:26
+  --> $DIR/named-asm-labels.rs:180:17
    |
-LL |     unsafe { naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1) }
-   |                          ^^^^^
+LL |     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:26
+  --> $DIR/named-asm-labels.rs:195:17
    |
-LL |     unsafe { naked_asm!(".Laaa: nop; ret;") }
-   |                          ^^^^^
+LL |     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:30
+  --> $DIR/named-asm-labels.rs:205:21
    |
-LL |         unsafe { naked_asm!(".Lbbb: nop; ret;") }
-   |                              ^^^^^
+LL |         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 77a67e0696eb2..d940decd561e9 100644
--- a/tests/ui/feature-gates/feature-gate-naked_functions.rs
+++ b/tests/ui/feature-gates/feature-gate-naked_functions.rs
@@ -3,20 +3,18 @@
 use std::arch::naked_asm;
 //~^ ERROR use of unstable library feature `naked_functions`
 
-#[naked]
+#[naked] //~ ERROR unsafe attribute used without unsafe
 //~^ ERROR the `#[naked]` attribute is an experimental feature
 extern "C" fn naked() {
     naked_asm!("")
     //~^ ERROR use of unstable library feature `naked_functions`
-    //~| ERROR: requires unsafe
 }
 
-#[naked]
+#[naked] //~ ERROR unsafe attribute used without unsafe
 //~^ ERROR the `#[naked]` attribute is an experimental feature
 extern "C" fn naked_2() -> isize {
     naked_asm!("")
     //~^ ERROR use of unstable library feature `naked_functions`
-    //~| ERROR: requires unsafe
 }
 
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-naked_functions.stderr b/tests/ui/feature-gates/feature-gate-naked_functions.stderr
index 9bfb9275bb201..ea765db7d946e 100644
--- a/tests/ui/feature-gates/feature-gate-naked_functions.stderr
+++ b/tests/ui/feature-gates/feature-gate-naked_functions.stderr
@@ -9,7 +9,7 @@ LL |     naked_asm!("")
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: use of unstable library feature `naked_functions`
-  --> $DIR/feature-gate-naked_functions.rs:17:5
+  --> $DIR/feature-gate-naked_functions.rs:16:5
    |
 LL |     naked_asm!("")
    |     ^^^^^^^^^
@@ -18,6 +18,28 @@ LL |     naked_asm!("")
    = help: add `#![feature(naked_functions)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
+error: unsafe attribute used without unsafe
+  --> $DIR/feature-gate-naked_functions.rs:6:3
+   |
+LL | #[naked]
+   |   ^^^^^ usage of unsafe attribute
+   |
+help: wrap the attribute in `unsafe(...)`
+   |
+LL | #[unsafe(naked)]
+   |   +++++++     +
+
+error: unsafe attribute used without unsafe
+  --> $DIR/feature-gate-naked_functions.rs:13:3
+   |
+LL | #[naked]
+   |   ^^^^^ usage of unsafe attribute
+   |
+help: wrap the attribute in `unsafe(...)`
+   |
+LL | #[unsafe(naked)]
+   |   +++++++     +
+
 error[E0658]: the `#[naked]` attribute is an experimental feature
   --> $DIR/feature-gate-naked_functions.rs:6:1
    |
@@ -29,7 +51,7 @@ LL | #[naked]
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the `#[naked]` attribute is an experimental feature
-  --> $DIR/feature-gate-naked_functions.rs:14:1
+  --> $DIR/feature-gate-naked_functions.rs:13:1
    |
 LL | #[naked]
    | ^^^^^^^^
@@ -48,23 +70,6 @@ LL | use std::arch::naked_asm;
    = help: add `#![feature(naked_functions)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0133]: use of inline assembly is unsafe and requires unsafe function or block
-  --> $DIR/feature-gate-naked_functions.rs:9:5
-   |
-LL |     naked_asm!("")
-   |     ^^^^^^^^^^^^^^ use of inline assembly
-   |
-   = note: inline assembly is entirely unchecked and can cause undefined behavior
-
-error[E0133]: use of inline assembly is unsafe and requires unsafe function or block
-  --> $DIR/feature-gate-naked_functions.rs:17:5
-   |
-LL |     naked_asm!("")
-   |     ^^^^^^^^^^^^^^ use of inline assembly
-   |
-   = note: inline assembly is entirely unchecked and can cause undefined behavior
-
 error: aborting due to 7 previous errors
 
-Some errors have detailed explanations: E0133, E0658.
-For more information about an error, try `rustc --explain E0133`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.rs b/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.rs
index c91d833994414..cc5b4f0e88b42 100644
--- a/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.rs
+++ b/tests/ui/feature-gates/feature-gate-naked_functions_rustic_abi.rs
@@ -5,19 +5,19 @@
 
 use std::arch::naked_asm;
 
-#[naked]
+#[unsafe(naked)]
 pub unsafe fn rust_implicit() {
     //~^ ERROR `#[naked]` is currently unstable on `extern "Rust"` functions
     naked_asm!("ret");
 }
 
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "Rust" fn rust_explicit() {
     //~^ ERROR `#[naked]` is currently unstable on `extern "Rust"` functions
     naked_asm!("ret");
 }
 
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "rust-cold" fn rust_cold() {
     //~^ ERROR `#[naked]` is currently unstable on `extern "rust-cold"` functions
     naked_asm!("ret");
diff --git a/tests/ui/feature-gates/feature-gate-naked_functions_target_feature.rs b/tests/ui/feature-gates/feature-gate-naked_functions_target_feature.rs
index 0d3af4c5fe0a4..b2e102f1db4b6 100644
--- a/tests/ui/feature-gates/feature-gate-naked_functions_target_feature.rs
+++ b/tests/ui/feature-gates/feature-gate-naked_functions_target_feature.rs
@@ -5,7 +5,7 @@
 
 use std::arch::naked_asm;
 
-#[naked]
+#[unsafe(naked)]
 #[target_feature(enable = "avx2")]
 //~^ ERROR: `#[target_feature(/* ... */)]` is currently unstable on `#[naked]` functions
 extern "C" fn naked() {
diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs
index 0e85515fd104a..ce6d10bf33cbd 100644
--- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs
+++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs
@@ -5,7 +5,7 @@ use std::arch::naked_asm;
 
 #[track_caller] //~ ERROR [E0736]
 //~^ ERROR `#[track_caller]` requires Rust ABI
-#[naked]
+#[unsafe(naked)]
 extern "C" fn f() {
     unsafe {
         naked_asm!("");
@@ -17,7 +17,7 @@ struct S;
 impl S {
     #[track_caller] //~ ERROR [E0736]
     //~^ ERROR `#[track_caller]` requires Rust ABI
-    #[naked]
+    #[unsafe(naked)]
     extern "C" fn g() {
         unsafe {
             naked_asm!("");
diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr
index 0625ed1183ba5..f89d94b67d806 100644
--- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr
+++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr
@@ -1,20 +1,20 @@
-error[E0736]: attribute incompatible with `#[naked]`
+error[E0736]: attribute incompatible with `#[unsafe(naked)]`
   --> $DIR/error-with-naked.rs:6:1
    |
 LL | #[track_caller]
-   | ^^^^^^^^^^^^^^^ the `track_caller` attribute is incompatible with `#[naked]`
+   | ^^^^^^^^^^^^^^^ the `track_caller` attribute is incompatible with `#[unsafe(naked)]`
 LL |
-LL | #[naked]
-   | -------- function marked with `#[naked]` here
+LL | #[unsafe(naked)]
+   | ---------------- function marked with `#[unsafe(naked)]` here
 
-error[E0736]: attribute incompatible with `#[naked]`
+error[E0736]: attribute incompatible with `#[unsafe(naked)]`
   --> $DIR/error-with-naked.rs:18:5
    |
 LL |     #[track_caller]
-   |     ^^^^^^^^^^^^^^^ the `track_caller` attribute is incompatible with `#[naked]`
+   |     ^^^^^^^^^^^^^^^ the `track_caller` attribute is incompatible with `#[unsafe(naked)]`
 LL |
-LL |     #[naked]
-   |     -------- function marked with `#[naked]` here
+LL |     #[unsafe(naked)]
+   |     ---------------- function marked with `#[unsafe(naked)]` here
 
 error[E0737]: `#[track_caller]` requires Rust ABI
   --> $DIR/error-with-naked.rs:6:1