Skip to content

Commit 71068af

Browse files
authored
Rollup merge of #145724 - folkertdev:track-caller-drop-no-mangle, r=fee1-dead
the `#[track_caller]` shim should not inherit `#[no_mangle]` fixes rust-lang/rust#143162 builds on rust-lang/rust#143293 which introduced a mechanism to strip attributes from shims. cc `@Jules-Bertholet` `@workingjubilee` `@bjorn3` --- Summary: This PR fixes an interaction between `#[track_caller]`, `#[no_mangle]`, and casting to a function pointer. A function annotated with `#[track_caller]` internally has a hidden extra argument for the panic location. The `#[track_caller]` attribute is only allowed on `extern "Rust"` functions. When a function is annotated with both `#[no_mangle]` and `#[track_caller]`, the exported symbol has the signature that includes the extra panic location argument. This works on stable rust today: ```rust extern "Rust" { #[track_caller] fn rust_track_caller_ffi_test_tracked() -> &'static Location<'static>; } mod provides { use std::panic::Location; #[track_caller] // UB if we did not have this! #[no_mangle] fn rust_track_caller_ffi_test_tracked() -> &'static Location<'static> { Location::caller() } } ``` When a `#[track_caller]` function is converted to a function pointer, a shim is added to drop the additional argument. So this is a valid program: ```rust #[track_caller] fn foo() {} fn main() { let f = foo as fn(); f(); } ``` The issue arises when `foo` is additionally annotated with `#[no_mangle]`, the generated shim currently inherits this attribute, also exporting a symbol named `foo`, but one without the hidden panic location argument. The linker rightfully complains about a duplicate symbol. The solution of this PR is to have the generated shim drop the `#[no_mangle]` attribute.
2 parents c15f855 + dd7c7d0 commit 71068af

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

src/abi/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
467467
true
468468
} else {
469469
instance.is_some_and(|inst| {
470-
fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD)
470+
fx.tcx.codegen_instance_attrs(inst.def).flags.contains(CodegenFnAttrFlags::COLD)
471471
})
472472
};
473473
if is_cold {

0 commit comments

Comments
 (0)