about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFolkert de Vries <folkert@folkertdev.nl>2025-04-14 14:36:53 +0200
committerFolkert de Vries <folkert@folkertdev.nl>2025-04-14 20:44:15 +0200
commitcb22c1d5e949b64aafb99994befde4bd25a421e9 (patch)
tree58f6e202c1c164026de0ae406e1a965c02414205
parent5961e5ba3daa20d98f549eb9029105ae50c13aed (diff)
downloadrust-cb22c1d5e949b64aafb99994befde4bd25a421e9.tar.gz
rust-cb22c1d5e949b64aafb99994befde4bd25a421e9.zip
Allow (but don't require) `#[unsafe(naked)]` so that `compiler-builtins` can upgrade to it
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs6
-rw-r--r--tests/ui/asm/naked-functions.rs56
2 files changed, 34 insertions, 28 deletions
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index 6a1c2af48ed..b518fca7a65 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -194,6 +194,12 @@ 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/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs
index 5bf2e2a3abd..8ba0eecb7b5 100644
--- a/tests/ui/asm/naked-functions.rs
+++ b/tests/ui/asm/naked-functions.rs
@@ -8,7 +8,7 @@
 
 use std::arch::{asm, naked_asm};
 
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "C" fn inline_asm_macro() {
     asm!("", options(raw));
     //~^ERROR the `asm!` macro is not allowed in naked functions
@@ -20,7 +20,7 @@ pub struct P {
     y: u16,
 }
 
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "C" fn patterns(
     mut a: u32,
     //~^ ERROR patterns not allowed in naked function parameters
@@ -34,27 +34,27 @@ pub unsafe extern "C" fn patterns(
     naked_asm!("")
 }
 
-#[naked]
+#[unsafe(naked)]
 pub unsafe 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
 }
 
-#[naked]
+#[unsafe(naked)]
 #[allow(asm_sub_register)]
 pub unsafe extern "C" fn inc_asm(a: u32) -> u32 {
     naked_asm!("/* {0} */", in(reg) a)
     //~^ ERROR the `in` operand cannot be used with `naked_asm!`
 }
 
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
     //~^ ERROR naked functions must contain a single `naked_asm!` invocation
     (|| a + 1)()
 }
 
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "C" fn unsupported_operands() {
     //~^ ERROR naked functions must contain a single `naked_asm!` invocation
     let mut a = 0usize;
@@ -76,12 +76,12 @@ pub unsafe extern "C" fn unsupported_operands() {
     );
 }
 
-#[naked]
+#[unsafe(naked)]
 pub extern "C" fn missing_assembly() {
     //~^ ERROR naked functions must contain a single `naked_asm!` invocation
 }
 
-#[naked]
+#[unsafe(naked)]
 pub extern "C" fn too_many_asm_blocks() {
     //~^ ERROR naked functions must contain a single `naked_asm!` invocation
     unsafe {
@@ -92,7 +92,7 @@ pub extern "C" fn too_many_asm_blocks() {
 }
 
 pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
-    #[naked]
+    #[unsafe(naked)]
     pub extern "C" fn inner(y: usize) -> usize {
         //~^ ERROR naked functions must contain a single `naked_asm!` invocation
         *&y
@@ -101,14 +101,14 @@ pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
     inner
 }
 
-#[naked]
+#[unsafe(naked)]
 unsafe extern "C" fn invalid_options() {
     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!`
 }
 
-#[naked]
+#[unsafe(naked)]
 unsafe extern "C" fn invalid_options_continued() {
     naked_asm!("", options(readonly, nostack), options(pure));
     //~^ ERROR the `readonly` option cannot be used with `naked_asm!`
@@ -116,20 +116,20 @@ unsafe extern "C" fn invalid_options_continued() {
     //~| ERROR the `pure` option cannot be used with `naked_asm!`
 }
 
-#[naked]
+#[unsafe(naked)]
 unsafe extern "C" fn invalid_may_unwind() {
     naked_asm!("", options(may_unwind));
     //~^ ERROR the `may_unwind` option cannot be used with `naked_asm!`
 }
 
-#[naked]
+#[unsafe(naked)]
 pub extern "C" fn valid_a<T>() -> T {
     unsafe {
         naked_asm!("");
     }
 }
 
-#[naked]
+#[unsafe(naked)]
 pub extern "C" fn valid_b() {
     unsafe {
         {
@@ -140,32 +140,32 @@ pub extern "C" fn valid_b() {
     }
 }
 
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "C" fn valid_c() {
     naked_asm!("");
 }
 
 #[cfg(target_arch = "x86_64")]
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "C" fn valid_att_syntax() {
     naked_asm!("", options(att_syntax));
 }
 
-#[naked]
-#[naked]
+#[unsafe(naked)]
+#[unsafe(naked)]
 pub unsafe extern "C" fn allow_compile_error(a: u32) -> u32 {
     compile_error!("this is a user specified error")
     //~^ ERROR this is a user specified error
 }
 
-#[naked]
+#[unsafe(naked)]
 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!("")
 }
 
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 {
     naked_asm!(invalid_syntax)
     //~^ ERROR asm template must be a string literal
@@ -173,7 +173,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)]
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "C" fn compatible_cfg_attributes() {
     naked_asm!("", options(att_syntax));
 }
@@ -182,20 +182,20 @@ pub unsafe extern "C" fn compatible_cfg_attributes() {
 #[warn(dead_code)]
 #[deny(dead_code)]
 #[forbid(dead_code)]
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "C" fn compatible_diagnostic_attributes() {
     naked_asm!("", options(raw));
 }
 
 #[deprecated = "test"]
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "C" fn compatible_deprecated_attributes() {
     naked_asm!("", options(raw));
 }
 
 #[cfg(target_arch = "x86_64")]
 #[must_use]
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
     naked_asm!(
         "
@@ -207,13 +207,13 @@ pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
 
 #[export_name = "exported_function_name"]
 #[link_section = ".custom_section"]
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "C" fn compatible_ffi_attributes_1() {
     naked_asm!("", options(raw));
 }
 
 #[cold]
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "C" fn compatible_codegen_attributes() {
     naked_asm!("", options(raw));
 }
@@ -222,13 +222,13 @@ pub unsafe extern "C" fn compatible_codegen_attributes() {
 /// a doc comment
 // a normal comment
 #[doc(alias = "ADocAlias")]
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "C" fn compatible_doc_attributes() {
     naked_asm!("", options(raw));
 }
 
 #[linkage = "external"]
-#[naked]
+#[unsafe(naked)]
 pub unsafe extern "C" fn compatible_linkage() {
     naked_asm!("", options(raw));
 }