<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, May 27, 2016 at 1:03 PM, Srivastava, Sunil via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">





<div lang="EN-US" link="#0563C1" vlink="#954F72">
<div>
<p class="MsoNormal">Hi,<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">I want to discuss the issue in PR27895,<u></u><u></u></p>
<p class="MsoNormal">       <a href="https://llvm.org/bugs/show_bug.cgi?id=27895" target="_blank">https://llvm.org/bugs/show_bug.cgi?id=27895</a><u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">But I will give a slightly different example for this discussion.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">The issue can be demonstrated by this standalone code. Should this example link<u></u><u></u></p>
<p class="MsoNormal">successfully?</p></div></div></blockquote><div><br></div><div>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:</div><div><br></div><div> 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)</div><div><br></div><div> 2) Clang CodeGen's devirtualization of obviously-devirtualizable calls should not devirtualize calls to linkonce_odr functions that it can't emit</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div lang="EN-US" link="#0563C1" vlink="#954F72"><div><p class="MsoNormal"><u></u><u></u></p>
<p class="MsoNormal">----------------------------------------------<u></u><u></u></p>
<p class="MsoNormal">template < typename T, int N = 0 > class TmplWithArray {<u></u><u></u></p>
<p class="MsoNormal">public:<u></u><u></u></p>
<p class="MsoNormal">  virtual T& operator [] (int idx);<u></u><u></u></p>
<p class="MsoNormal">  T ar[N+1];<u></u><u></u></p>
<p class="MsoNormal">};<u></u><u></u></p>
<p class="MsoNormal">template <typename T, int N> T& TmplWithArray<T, N >::operator[](int idx) {<u></u><u></u></p>
<p class="MsoNormal">  return ar[idx];<u></u><u></u></p>
<p class="MsoNormal">}<u></u><u></u></p>
<p class="MsoNormal">class Wrapper {<u></u><u></u></p>
<p class="MsoNormal">  TmplWithArray<bool, 10> data;<u></u><u></u></p>
<p class="MsoNormal">  bool indexIt(int a);<u></u><u></u></p>
<p class="MsoNormal">};<u></u><u></u></p>
<p class="MsoNormal">bool Wrapper::indexIt(int a)<u></u><u></u></p>
<p class="MsoNormal">{<u></u><u></u></p>
<p class="MsoNormal">   return data[a];<u></u><u></u></p>
<p class="MsoNormal">}<u></u><u></u></p>
<p class="MsoNormal">int main(){}<u></u><u></u></p>
<p class="MsoNormal">----------------------------------------------<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Starting from  r227073 it does not link (at any optimization level). The code<u></u><u></u></p>
<p class="MsoNormal">has a direct call to the operator[] function, but that function definition is<u></u><u></u></p>
<p class="MsoNormal">not generated.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Versions prior to r227073,<u></u><u></u></p>
<p class="MsoNormal">    -  at –O0 or –O1, generate the operator[] function and the direct call, and<u></u><u></u></p>
<p class="MsoNormal">    -  at –O2 do not generate the function, but inline it<u></u><u></u></p>
<p class="MsoNormal">Either way they link fine.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">In this example the key-function for the generation of the vtable is the<u></u><u></u></p>
<p class="MsoNormal">operator[] function itself.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">So the compiler can either generate both the vtable and the operator[]<u></u><u></u></p>
<p class="MsoNormal">function, or not generate either; they are both consistent states.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">The call in data[a] is to a virtual function, and if the compiler left it as a<u></u><u></u></p>
<p class="MsoNormal">virtual call, it will link. There will be no ctor, no vtable, and no operator[]<u></u><u></u></p>
<p class="MsoNormal">function. Wrapper::indexIt will be dead code, but it will link.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">But the compiler does devirtualization of the call and generates a direct call,<u></u><u></u></p>
<p class="MsoNormal">yet, beginning with r227073, it does not generate the operator[] function.<u></u><u></u></p>
<p class="MsoNormal">Hence the link failure.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Another interesting tidbit is that if the operator[] is replaced by a plain<u></u><u></u></p>
<p class="MsoNormal">function doing the same thing, along with the corresponding change in the
<u></u><u></u></p>
<p class="MsoNormal">usage, something like:<u></u><u></u></p>
<p class="MsoNormal">    virtual T& getElt(int idx);<u></u><u></u></p>
<p class="MsoNormal">then the behavior is the same as pre r227073. Either getElt is defined or it<u></u><u></u></p>
<p class="MsoNormal">gets inlined.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">BTW, this is not just an idle curiosity. This example was trimmed down from<u></u><u></u></p>
<p class="MsoNormal">a user bug report having a link failure.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Sunil Srivastava<u></u><u></u></p>
<p class="MsoNormal">Sony Interactive Entertainment<u></u><u></u></p>
</div>
</div>

<br>_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
<br></blockquote></div><br></div></div>