Skip to content
3 changes: 3 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,9 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
}

let prefix = match &target.arch[..] {
"x86" | "x86_64" if target.is_like_msvc && undecorated.starts_with("?") => {
return undecorated;
}
"x86" => Some('_'),
"x86_64" => None,
// Only functions are decorated for arm64ec.
Expand Down
25 changes: 25 additions & 0 deletions tests/ui/symbol-names/symbol-with-question-mark-links.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// This test ensures functions with an exported name beginning with a question mark
// successfully compile and link.
//
// Regression test for <https://github.com/rust-lang/rust/issues/44282>

//@ build-pass
//@ only-windows
//@ only-x86
// Reason: This test regards a linker issue which only applies to Windows.
// Specifically, it only occurs due to Windows x86 name decoration, combined with
// a mismatch between LLVM's decoration logic and Rust's (for `lib.def` generation)

#![crate_type = "cdylib"]

#[no_mangle]
pub extern "C" fn decorated(a: i32, b: i32) -> i32 {
1
}

// This isn't just `?undecorated` because MSVC's linker fails if the decorated
// symbol is not valid.
#[export_name = "?undecorated@@YAXXZ"]
pub extern "C" fn undecorated(a: i32, b: i32) -> i32 {
2
}
Loading