[PATCH] Fix linkage for vtables of class template specializations with explicit instantiation declarations
John McCall
rjmccall at apple.com
Fri Feb 15 16:34:15 PST 2013
On Feb 14, 2013, at 8:07 PM, Richard Smith <richard at metafoo.co.uk> wrote:
> 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.
>
> 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.
>
> So this patch makes two changes:
> 1) Emit externally-available primary vtables and VTTs as available_externally rather than linkonce_odr, and
> 2) Emit externally-available construction vtables as internal rather than linkonce_odr.
>
> 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.
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.
So what I'm saying is that yes, this approach sounds fine.
> 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.
Emitting them internally is fine. They're marked "const unnamed_addr"; maybe we can teach LTO (and/or real linkers) to merge them.
John.
More information about the cfe-commits
mailing list