Reid commented on http://reviews.llvm.org/D3877?id=9937#inline-32885 that WeakAny didn't seem like the right linkage.
Details
Details
Diff Detail
Diff Detail
- Repository
- rL LLVM
Event Timeline
Comment Actions
I think it's handling this corner case:
struct Incomplete; struct A { int a; virtual A *bar(); }; struct B { int b; virtual B *foo(Incomplete); }; struct C : A, B { int c; virtual C *foo(Incomplete); }; C c;
MSVC gives this error:
t.cpp(5) : error C2664: 'C *C::foo(Incomplete)' : cannot convert argument 1 from 'Incomplete' to 'Incomplete' Source or target has incomplete type This diagnostic occurred in the compiler generated function 'B *C::foo(Incomplete)'
Clang on the other hand relies on the TU defining the virtual function to emit code for the thunk. Therefore I think the correct linkage is weak_odr. This should also be applicable to the Itanium C++ ABI.
Comment Actions
It occurs to me that the linkage is still wrong for classes with thunks in anonymous namespaces. It'd also be nice to have the thunks be discardable (i.e. linkonce_odr) in the common cases.
I think this is the right linkage computation:
- class has GVA_Internal linkage -> thunk is internal
- the thunk has a return adjustment -> thunk is weak_odr, to handle the evil corner case
- all other normal methods -> thunk is linkonce_odr