Missing definition of a template virtual function

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Fri May 27 15:15:35 PDT 2016


On Fri, May 27, 2016 at 1:03 PM, Srivastava, Sunil via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Hi,
>
>
>
> I want to discuss the issue in PR27895,
>
>        https://llvm.org/bugs/show_bug.cgi?id=27895
>
>
>
> But I will give a slightly different example for this discussion.
>
>
>
> The issue can be demonstrated by this standalone code. Should this example
> link
>
> successfully?
>

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 at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160527/6ada7c4d/attachment.html>


More information about the cfe-commits mailing list