On Fri, Feb 15, 2013 at 4:34 PM, John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On Feb 14, 2013, at 8:07 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br>
> If a class template specialization has an explicit instantiation declaration and needs a VTT, we currently emit all the vtable data as linkonce_odr. That causes link failures in some cases, because recent g++ versions put all the vtable-related data in a COMDAT, and if we emit some of the symbols but not all of them, we can cause the COMDAT from the explicit instantiation definition to not be chosen, resulting in missing symbols.<br>

><br>
> This patch fixes that and removes some FIXMEs by switching us to available_externally. However, testing that fix revealed another problem: if (through inlining and constant propagation through the VTT) we end up with a reference to a construction vtable in the generated code, we will sometimes have no definition for that construction vtable. This is because the Itanium ABI does not require a compiler to emit construction vtables with any particular mangling or linkage, and indeed recent versions of libstdc++.so make all the construction vtable symbols internal.<br>

><br>
> So this patch makes two changes:<br>
> 1) Emit externally-available primary vtables and VTTs as available_externally rather than linkonce_odr, and<br>
> 2) Emit externally-available construction vtables as internal rather than linkonce_odr.<br>
><br>
> I believe point (2) conforms to the ABI -- while we're required to use the same primary vtable for all objects of the same most-derived type, the same restriction does not appear to apply to construction vtables.<br>

<br>
</div>Er, I don't remember (and can't find) a requirement that all objects of the same most-derived type must use the same non-construction virtual table group, and I can't think of what would rely on that guarantee.  That would invalidate a number of optimizations we do, e.g. the optimization where we give linkonce_odr v-tables and RTTI objects (but not RTTI names) hidden visibility.<br>
</blockquote><div><br></div><div>I was referring to Itanium ABI, 2.5.1, first paragraph: "There may be multiple virtual tables for a particular class, if it is used as a base class for other classes. However, the virtual table pointers within all the objects (instances) of a particular most-derived class point to the same set of virtual tables."</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
So what I'm saying is that yes, this approach sounds fine.</blockquote><div><br></div><div>Great, thanks, r175330.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">
> If duplicating the construction vtables concerns you (in the rare case where we manage to propagate the address of one out of the VTT), I'd be fine with never emitting externally-available VTTs instead -- but that will lose us some optimization opportunities.<br>

<br>
</div>Emitting them internally is fine.  They're marked "const unnamed_addr";  maybe we can teach LTO (and/or real linkers) to merge them.<br>
<span class="HOEnZb"><font color="#888888"><br>
John.<br>
</font></span></blockquote></div><br>