Rollup merge of #145724 - folkertdev:track-caller-drop-no-mangle, r=fee1-dead
the `#[track_caller]` shim should not inherit `#[no_mangle]` fixes https://github.com/rust-lang/rust/issues/143162 builds on https://github.com/rust-lang/rust/pull/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.
This commit is contained in:
@@ -245,7 +245,7 @@ impl<'tcx> Inliner<'tcx> for ForceInliner<'tcx> {
|
||||
fn on_inline_failure(&self, callsite: &CallSite<'tcx>, reason: &'static str) {
|
||||
let tcx = self.tcx();
|
||||
let InlineAttr::Force { attr_span, reason: justification } =
|
||||
tcx.codegen_fn_attrs(callsite.callee.def_id()).inline
|
||||
tcx.codegen_instance_attrs(callsite.callee.def).inline
|
||||
else {
|
||||
bug!("called on item without required inlining");
|
||||
};
|
||||
@@ -603,7 +603,8 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
|
||||
let tcx = inliner.tcx();
|
||||
check_mir_is_available(inliner, caller_body, callsite.callee)?;
|
||||
|
||||
let callee_attrs = tcx.codegen_fn_attrs(callsite.callee.def_id());
|
||||
let callee_attrs = tcx.codegen_instance_attrs(callsite.callee.def);
|
||||
let callee_attrs = callee_attrs.as_ref();
|
||||
check_inline::is_inline_valid_on_fn(tcx, callsite.callee.def_id())?;
|
||||
check_codegen_attributes(inliner, callsite, callee_attrs)?;
|
||||
inliner.check_codegen_attributes_extra(callee_attrs)?;
|
||||
|
||||
Reference in New Issue
Block a user