Hi John,<div><br></div><div>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.</div>
<div><br></div><div>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.</div>
<div><br></div><div>So this patch makes two changes:</div><div>1) Emit externally-available primary vtables and VTTs as available_externally rather than linkonce_odr, and</div><div>2) Emit externally-available construction vtables as internal rather than linkonce_odr.</div>
<div><br></div><div>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.</div>
<div><br></div><div>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.</div>
<div><br></div><div>Thanks,</div><div>Richard</div>