summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_codegen_llvm/src/callee.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/callee.rs')
-rw-r--r--compiler/rustc_codegen_llvm/src/callee.rs15
1 files changed, 14 insertions, 1 deletions
diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs
index 6f0d1b7ce..70ff5c961 100644
--- a/compiler/rustc_codegen_llvm/src/callee.rs
+++ b/compiler/rustc_codegen_llvm/src/callee.rs
@@ -83,7 +83,20 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
let llfn = if tcx.sess.target.arch == "x86" &&
let Some(dllimport) = common::get_dllimport(tcx, instance_def_id, sym)
{
- cx.declare_fn(&common::i686_decorated_name(&dllimport, common::is_mingw_gnu_toolchain(&tcx.sess.target), true), fn_abi)
+ // Fix for https://github.com/rust-lang/rust/issues/104453
+ // On x86 Windows, LLVM uses 'L' as the prefix for any private
+ // global symbols, so when we create an undecorated function symbol
+ // that begins with an 'L' LLVM misinterprets that as a private
+ // global symbol that it created and so fails the compilation at a
+ // later stage since such a symbol must have a definition.
+ //
+ // To avoid this, we set the Storage Class to "DllImport" so that
+ // LLVM will prefix the name with `__imp_`. Ideally, we'd like the
+ // existing logic below to set the Storage Class, but it has an
+ // exemption for MinGW for backwards compatability.
+ let llfn = cx.declare_fn(&common::i686_decorated_name(&dllimport, common::is_mingw_gnu_toolchain(&tcx.sess.target), true), fn_abi);
+ unsafe { llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); }
+ llfn
} else {
cx.declare_fn(sym, fn_abi)
};