<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Jun 14, 2016 at 12:51 PM, David Blaikie via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="gmail-">On Sat, Jun 4, 2016 at 9:36 AM, Piotr Padlewski <span dir="ltr"><<a href="mailto:piotr.padlewski@gmail.com">piotr.padlewski@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr">Sorry, my bad - there was a problem with available_externally vtables that we were unable to generate when there was a inline virtual function. </div></blockquote><div><br></div></span><div>Ah, I've found the code and some of the comments for that - do you remember the details or have pointers to the related threads/reviews/etc that came to that conclusion?<br><br>Could we not emit the inline functions as linkonce_odr as usual and then emit the available_externally vtable on top of that. Presumably once we do all the optimization and drop the vtable, any of these inline virtual functions that haven't got any devirtualized calls to them will disappear due to lacking any reference holding them alive.<br><br>It'd bloat object files a bit, but only in the cases where there's an optimization win - right?<br><br>But I guess there's a reason that doesn't work/wasn't implemented.</div></div></div></div></blockquote><div><br></div><div>It's complicated. Here's an interesting test case where it is hard to generate an available_externally vtable for C:</div><div><br></div><div>#include <memory></div><div>struct A;</div><div>struct B {</div><div>  virtual void ~B();<br>};</div><div>struct C : B {</div><div>  C();</div><div>  virtual void f();</div><div>  std::unique_ptr<A> a;<br>};</div><div>C *getit() {</div><div>  C *p = new C;</div><div>  p->f();</div><div>  return p;<br>}</div><div><br></div><div>In order to emit an externally_available vtable, we need to emit all the inline virtual functions as linkonce_odr, which requires semantically checking them up front, which would implicitly define ~C, which would instantiate ~unique_ptr<A>, which requires A to be complete.<br></div><div><br></div><div>The question is, are we allowed to require 'A' to be a complete type so that we can emit the implicit definition of C::~C?</div><div><br></div><div>Blink/WebKit/Nico want the answer to be "no", and most compilers give that answer, because there is no vtable reference required here to generate code. Richard's interpretation of the standard says that the call to the virtual function 'f' allows us to do the semantic checking, so we could change our minds if we think it's worth the hassle of compatibility issues and user confusion.</div><div><br></div><div>I think it will be very hard to explain to users why 'A' needs to be complete, since there's no clear vtable reference. We would need a diagnostic note saying that the vtable was required to be complete at this virtual call to support devirtualization.</div></div></div></div>