Skip to content

Commit 13c99b9

Browse files
Fix symbol resolution in get_fn to prefer dll imports
1 parent be0ade2 commit 13c99b9

File tree

1 file changed

+37
-39
lines changed

1 file changed

+37
-39
lines changed

compiler/rustc_codegen_llvm/src/callee.rs

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -31,47 +31,45 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t
3131

3232
let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty());
3333

34-
let llfn = if let Some(llfn) = cx.get_declared_value(sym) {
34+
let instance_def_id = instance.def_id();
35+
let existing_decl = cx.get_declared_value(sym);
36+
37+
let llfn = if tcx.sess.target.arch == "x86"
38+
&& let Some(dllimport) = get_dllimport(tcx, instance_def_id, sym) {
39+
// When calling functions in generated import libraries, MSVC needs
40+
// the fully decorated name (as would have been in the declaring
41+
// object file), but MinGW wants the name as exported (as would be
42+
// in the def file) which may be missing decorations.
43+
let mingw_gnu_toolchain = common::is_mingw_gnu_toolchain(&tcx.sess.target);
44+
let llfn = cx.declare_fn(
45+
&common::i686_decorated_name(
46+
dllimport,
47+
mingw_gnu_toolchain,
48+
true,
49+
!mingw_gnu_toolchain,
50+
),
51+
fn_abi,
52+
Some(instance),
53+
);
54+
55+
// Fix for https://github.com/rust-lang/rust/issues/104453
56+
// On x86 Windows, LLVM uses 'L' as the prefix for any private
57+
// global symbols, so when we create an undecorated function symbol
58+
// that begins with an 'L' LLVM misinterprets that as a private
59+
// global symbol that it created and so fails the compilation at a
60+
// later stage since such a symbol must have a definition.
61+
//
62+
// To avoid this, we set the Storage Class to "DllImport" so that
63+
// LLVM will prefix the name with `__imp_`. Ideally, we'd like the
64+
// existing logic below to set the Storage Class, but it has an
65+
// exemption for MinGW for backwards compatibility.
66+
llvm::set_dllimport_storage_class(llfn);
3567
llfn
3668
} else {
37-
let instance_def_id = instance.def_id();
38-
let llfn = if tcx.sess.target.arch == "x86"
39-
&& let Some(dllimport) = crate::common::get_dllimport(tcx, instance_def_id, sym)
40-
{
41-
// When calling functions in generated import libraries, MSVC needs
42-
// the fully decorated name (as would have been in the declaring
43-
// object file), but MinGW wants the name as exported (as would be
44-
// in the def file) which may be missing decorations.
45-
let mingw_gnu_toolchain = common::is_mingw_gnu_toolchain(&tcx.sess.target);
46-
let llfn = cx.declare_fn(
47-
&common::i686_decorated_name(
48-
dllimport,
49-
mingw_gnu_toolchain,
50-
true,
51-
!mingw_gnu_toolchain,
52-
),
53-
fn_abi,
54-
Some(instance),
55-
);
56-
57-
// Fix for https://github.com/rust-lang/rust/issues/104453
58-
// On x86 Windows, LLVM uses 'L' as the prefix for any private
59-
// global symbols, so when we create an undecorated function symbol
60-
// that begins with an 'L' LLVM misinterprets that as a private
61-
// global symbol that it created and so fails the compilation at a
62-
// later stage since such a symbol must have a definition.
63-
//
64-
// To avoid this, we set the Storage Class to "DllImport" so that
65-
// LLVM will prefix the name with `__imp_`. Ideally, we'd like the
66-
// existing logic below to set the Storage Class, but it has an
67-
// exemption for MinGW for backwards compatibility.
68-
llvm::set_dllimport_storage_class(llfn);
69-
llfn
70-
} else {
71-
cx.declare_fn(sym, fn_abi, Some(instance))
72-
};
73-
debug!("get_fn: not casting pointer!");
69+
existing_decl.unwrap_or_else(|| cx.declare_fn(sym, fn_abi, Some(instance)))
70+
};
7471

72+
if existing_decl.map_or(true, |existing| existing != llfn) {
7573
// Apply an appropriate linkage/visibility value to our item that we
7674
// just declared.
7775
//
@@ -152,7 +150,7 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t
152150
cx.assume_dso_local(llfn, true);
153151

154152
llfn
155-
};
153+
}
156154

157155
cx.instances.borrow_mut().insert(instance, llfn);
158156

0 commit comments

Comments
 (0)