From 07c7e5ffb3c096f80ffede421fb20089fbe7fe3f Mon Sep 17 00:00:00 2001 From: Alexandru RADOVICI Date: Wed, 30 Apr 2025 14:52:15 +0300 Subject: [PATCH] error when using no_mangle on language items add suggestion on how to add a panic breakpoint Co-authored-by: Pat Pannuto delete no_mangle from ui/panic-handler/panic-handler-wrong-location test issue an error for the usage of #[no_mangle] on internal language items delete the comments add newline rephrase note Co-authored-by: bjorn3 <17426603+bjorn3@users.noreply.github.com> update error not to leak implementation details delete no_mangle_span Co-authored-by: bjorn3 <17426603+bjorn3@users.noreply.github.com> delete commented code --- .../rustc_codegen_ssa/src/codegen_attrs.rs | 30 +++++++++++++++++++ .../no-mangle-on-internal-lang-items.rs | 14 +++++++++ .../no-mangle-on-internal-lang-items.stderr | 12 ++++++++ .../ui/codegen/no-mangle-on-panic-handler.rs | 14 +++++++++ .../codegen/no-mangle-on-panic-handler.stderr | 16 ++++++++++ .../panic-handler-wrong-location.rs | 1 - 6 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 tests/ui/codegen/no-mangle-on-internal-lang-items.rs create mode 100644 tests/ui/codegen/no-mangle-on-internal-lang-items.stderr create mode 100644 tests/ui/codegen/no-mangle-on-panic-handler.rs create mode 100644 tests/ui/codegen/no-mangle-on-panic-handler.stderr diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index b0c53ec93ce17..5d09e62f2742d 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 0000000000000..37766936410ed --- /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 0000000000000..12461a6abb964 --- /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 0000000000000..1dc0cce0a2ece --- /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 0000000000000..dc88b66d1b5d7 --- /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 c91580ae0c4ce..8fff7067136e2 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