The LTO/ThinLTO driver currently creates invalid bitcode by setting
symbols marked dllimport as dso_local. The compiler often has access
to the definition (often dllexport) and the declaration (often
dllimport) of an object at link-time, leading to a conflicting
declaration. This patch resolves the inconsistency by removing the
dllimport attribute.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
Why add dllexport instead of just removing dllimport as was done before? This often happens in situations involving inline methods of templates, and I don't think it would be correct to export such inline functions. I also wouldn't want LTO to suddenly export a bunch of things that the native linker wouldn't export. By the way, this situation is covered by the LNK4049 and LNK4217 warnings in the Microsoft linker.
Here's an example of a situation where you might get accidental incorrect imports: https://gcc.godbolt.org/z/VAl5Kn
void g(int); template <typename T> struct Foo { static void f() { g(sizeof(T)); } }; // Uncomment Bar to see Foo<int>::f get imported //struct __declspec(dllimport) Bar : Foo<int> {}; void h() { Foo<int>::f(); }
I don't think it would be correct to upgrade Foo<int>::f to dllexport.
That makes sense. Here's an updated diff.
Changelog:
- Remove dllimport instead of replacing it.
- Remove unnecessary test change.
include/llvm/IR/GlobalValue.h | ||
---|---|---|
198–199 ↗ | (On Diff #178784) | This change doesn't seem quite right. On the one hand, if a GlobalValue has internal linkage, it probably shouldn't be marked dllimport. However, we really shouldn't look at visibility or external weak linkage, which are concepts that don't exist for COFF. And we probably shouldn't adjust the dll storage class from a function named maybeSetDsoLocal. |
lib/LTO/LTO.cpp | ||
698–700 ↗ | (On Diff #178784) | This looks like the important functional change. Would the test still pass if you reverted the changes other than this one? |