about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs30
-rw-r--r--tests/ui/codegen/no-mangle-on-internal-lang-items.rs14
-rw-r--r--tests/ui/codegen/no-mangle-on-internal-lang-items.stderr12
-rw-r--r--tests/ui/codegen/no-mangle-on-panic-handler.rs14
-rw-r--r--tests/ui/codegen/no-mangle-on-panic-handler.stderr16
-rw-r--r--tests/ui/panic-handler/panic-handler-wrong-location.rs1
6 files changed, 86 insertions, 1 deletions
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index b0c53ec93ce..5d09e62f274 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -87,6 +87,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
     let mut link_ordinal_span = None;
     let mut no_sanitize_span = None;
     let mut mixed_export_name_no_mangle_lint_state = MixedExportNameAndNoMangleState::default();
+    let mut no_mangle_span = None;
 
     for attr in attrs.iter() {
         // In some cases, attribute are only valid on functions, but it's the `check_attr`
@@ -139,6 +140,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
             }
             sym::naked => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
             sym::no_mangle => {
+                no_mangle_span = Some(attr.span());
                 if tcx.opt_item_name(did.to_def_id()).is_some() {
                     codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
                     mixed_export_name_no_mangle_lint_state.track_no_mangle(
@@ -621,6 +623,34 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
     }
     check_link_name_xor_ordinal(tcx, &codegen_fn_attrs, link_ordinal_span);
 
+    if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
+        && codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
+    {
+        let lang_item =
+            lang_items::extract(attrs).map_or(None, |(name, _span)| LangItem::from_name(name));
+        let mut err = tcx
+            .dcx()
+            .struct_span_err(
+                no_mangle_span.unwrap_or_default(),
+                "`#[no_mangle]` cannot be used on internal language items",
+            )
+            .with_note("Rustc requires this item to have a specific mangled name.")
+            .with_span_label(tcx.def_span(did), "should be the internal language item");
+        if let Some(lang_item) = lang_item {
+            if let Some(link_name) = lang_item.link_name() {
+                err = err
+                    .with_note("If you are trying to prevent mangling to ease debugging, many")
+                    .with_note(format!(
+                        "debuggers support a command such as `rbreak {link_name}` to"
+                    ))
+                    .with_note(format!(
+                        "match `.*{link_name}.*` instead of `break {link_name}` on a specific name"
+                    ))
+            }
+        }
+        err.emit();
+    }
+
     // Any linkage to LLVM intrinsics for now forcibly marks them all as never
     // unwinds since LLVM sometimes can't handle codegen which `invoke`s
     // intrinsic functions.
diff --git a/tests/ui/codegen/no-mangle-on-internal-lang-items.rs b/tests/ui/codegen/no-mangle-on-internal-lang-items.rs
new file mode 100644
index 00000000000..37766936410
--- /dev/null
+++ b/tests/ui/codegen/no-mangle-on-internal-lang-items.rs
@@ -0,0 +1,14 @@
+// Issue a error when the user uses #[no_mangle] on internal language items
+//@ edition:2024
+
+#![feature(rustc_attrs)]
+
+#[rustc_std_internal_symbol]
+#[unsafe(no_mangle)] //~ERROR `#[no_mangle]` cannot be used on internal language items
+fn internal_lang_function () {
+
+}
+
+fn main() {
+
+}
diff --git a/tests/ui/codegen/no-mangle-on-internal-lang-items.stderr b/tests/ui/codegen/no-mangle-on-internal-lang-items.stderr
new file mode 100644
index 00000000000..12461a6abb9
--- /dev/null
+++ b/tests/ui/codegen/no-mangle-on-internal-lang-items.stderr
@@ -0,0 +1,12 @@
+error: `#[no_mangle]` cannot be used on internal language items
+  --> $DIR/no-mangle-on-internal-lang-items.rs:7:1
+   |
+LL | #[unsafe(no_mangle)]
+   | ^^^^^^^^^^^^^^^^^^^^
+LL | fn internal_lang_function () {
+   | ---------------------------- should be the internal language item
+   |
+   = note: Rustc requires this item to have a specific mangled name.
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/codegen/no-mangle-on-panic-handler.rs b/tests/ui/codegen/no-mangle-on-panic-handler.rs
new file mode 100644
index 00000000000..1dc0cce0a2e
--- /dev/null
+++ b/tests/ui/codegen/no-mangle-on-panic-handler.rs
@@ -0,0 +1,14 @@
+// Issue an error when the user uses #[no_mangle] on the panic handler
+//@ edition:2024
+
+#![crate_type="lib"]
+#![no_std]
+#![no_main]
+
+use core::panic::PanicInfo;
+
+#[unsafe(no_mangle)] //~ ERROR `#[no_mangle]` cannot be used on internal language items
+#[panic_handler]
+pub unsafe fn panic_fmt(pi: &PanicInfo) -> ! {
+    loop {}
+}
diff --git a/tests/ui/codegen/no-mangle-on-panic-handler.stderr b/tests/ui/codegen/no-mangle-on-panic-handler.stderr
new file mode 100644
index 00000000000..dc88b66d1b5
--- /dev/null
+++ b/tests/ui/codegen/no-mangle-on-panic-handler.stderr
@@ -0,0 +1,16 @@
+error: `#[no_mangle]` cannot be used on internal language items
+  --> $DIR/no-mangle-on-panic-handler.rs:10:1
+   |
+LL | #[unsafe(no_mangle)]
+   | ^^^^^^^^^^^^^^^^^^^^
+LL | #[panic_handler]
+LL | pub unsafe fn panic_fmt(pi: &PanicInfo) -> ! {
+   | -------------------------------------------- should be the internal language item
+   |
+   = note: Rustc requires this item to have a specific mangled name.
+   = note: If you are trying to prevent mangling to ease debugging, many
+   = note: debuggers support a command such as `rbreak rust_begin_unwind` to
+   = note: match `.*rust_begin_unwind.*` instead of `break rust_begin_unwind` on a specific name
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/panic-handler/panic-handler-wrong-location.rs b/tests/ui/panic-handler/panic-handler-wrong-location.rs
index c91580ae0c4..8fff7067136 100644
--- a/tests/ui/panic-handler/panic-handler-wrong-location.rs
+++ b/tests/ui/panic-handler/panic-handler-wrong-location.rs
@@ -4,7 +4,6 @@
 #![no_main]
 
 #[panic_handler] //~ ERROR `panic_impl` lang item must be applied to a function
-#[no_mangle]
 static X: u32 = 42;
 
 //~? ERROR `#[panic_handler]` function required, but not found