@@ -83,7 +83,20 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
83
83
let llfn = if tcx. sess . target . arch == "x86" &&
84
84
let Some ( dllimport) = common:: get_dllimport ( tcx, instance_def_id, sym)
85
85
{
86
- cx. declare_fn ( & common:: i686_decorated_name ( & dllimport, common:: is_mingw_gnu_toolchain ( & tcx. sess . target ) , true ) , fn_abi)
86
+ // Fix for https://github.com/rust-lang/rust/issues/104453
87
+ // On x86 Windows, LLVM uses 'L' as the prefix for any private
88
+ // global symbols, so when we create an undecorated function symbol
89
+ // that begins with an 'L' LLVM misinterprets that as a private
90
+ // global symbol that it created and so fails the compilation at a
91
+ // later stage since such a symbol must have a definition.
92
+ //
93
+ // To avoid this, we set the Storage Class to "DllImport" so that
94
+ // LLVM will prefix the name with `__imp_`. Ideally, we'd like the
95
+ // existing logic below to set the Storage Class, but it has an
96
+ // exemption for MinGW for backwards compatability.
97
+ let llfn = cx. declare_fn ( & common:: i686_decorated_name ( & dllimport, common:: is_mingw_gnu_toolchain ( & tcx. sess . target ) , true ) , fn_abi) ;
98
+ unsafe { llvm:: LLVMSetDLLStorageClass ( llfn, llvm:: DLLStorageClass :: DllImport ) ; }
99
+ llfn
87
100
} else {
88
101
cx. declare_fn ( sym, fn_abi)
89
102
} ;
0 commit comments