Hi Richard, Thanks for you analysis. I have some follow up questions though:
First, either of these two suggestions below should fix the bug, though it may be better to do both. Right ? Then, approach (2) has a cost. It will prevent devirtualizations of calls which could get defined elsewhere. While my example of https://llvm.org/bugs/show_bug.cgi?id=27895#c4 is good for demonstrating the bug, it is an unusual case. The usual case is that the template will be defined somewhere. So by suppressing devirtualization in this case we will be penalizing the usual cases to fix a bug in unusual cases. The approach (1) is doable of course. It involves passing some kind of isFullObject flag few levels down in SemaOverload.cpp, and then prevent reset of OdrUse flag if isFullObject is true. However I want to understand better what is going on here. Specifically, why virtual operators are treated different from virtual functions. In my example, if you replace the operator[] with a plain function doing the same thing, the function definition gets generated. In your bugzilla comment 5, you perhaps alluded to this point: > we model operator[] as weak_odr unnamed_addr, which would allow us to > discard the symbol in the other translation unit if we can merge the > function with something else, even though its address is exposed in > the vtable But what can the compiler do with user written operator[] that it can not do with a plain function ? Beside, this bug is not just with operator[]. It is with every member operator. Thanks Sunil Srivastava Sony Interactive Entertainment Yes, this is a bug. We emit a direct call to TmplWithArray<bool,10>::operator[] so we're required to also emit a definition of it. I think the code that r227073 removed was really masking this bug rather than fixing it. It seems like there are two issues here: 1) Sema should mark a virtual function as used if it sees an obviously-devirtualizable call to the function (where the base object has a known dynamic type) 2) Clang CodeGen's devirtualization of obviously-devirtualizable calls should not devirtualize calls to linkonce_odr functions that it can't emit ---------------------------------------------- template < typename T, int N = 0 > class TmplWithArray { public: virtual T& operator [] (int idx); T ar[N+1]; }; template <typename T, int N> T& TmplWithArray<T, N >::operator[](int idx) { return ar[idx]; } class Wrapper { TmplWithArray<bool, 10> data; bool indexIt(int a); }; bool Wrapper::indexIt(int a) { return data[a]; } int main(){} ---------------------------------------------- Starting from r227073 it does not link (at any optimization level). The code has a direct call to the operator[] function, but that function definition is not generated. Versions prior to r227073, - at –O0 or –O1, generate the operator[] function and the direct call, and - at –O2 do not generate the function, but inline it Either way they link fine. In this example the key-function for the generation of the vtable is the operator[] function itself. So the compiler can either generate both the vtable and the operator[] function, or not generate either; they are both consistent states. The call in data[a] is to a virtual function, and if the compiler left it as a virtual call, it will link. There will be no ctor, no vtable, and no operator[] function. Wrapper::indexIt will be dead code, but it will link. But the compiler does devirtualization of the call and generates a direct call, yet, beginning with r227073, it does not generate the operator[] function. Hence the link failure. Another interesting tidbit is that if the operator[] is replaced by a plain function doing the same thing, along with the corresponding change in the usage, something like: virtual T& getElt(int idx); then the behavior is the same as pre r227073. Either getElt is defined or it gets inlined. BTW, this is not just an idle curiosity. This example was trimmed down from a user bug report having a link failure. Sunil Srivastava Sony Interactive Entertainment _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org<mailto:cfe-commits@lists.llvm.org> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits