The change to elide the "base object constructor" for final classes in bug #70462 introduces an ABI incompatibility with clang 9 at least. I'm seeing this with kuduraft-1.8 compiled with GCC 10, giving linker errors from clang 9.0.20190721 like: error: undefined symbol: kudu::consensus::OpId::OpId() Reverting the change in #70462 fixes the issue
Can you provide a full testcase? From the sound of it, this might be a LLVM bug. As mentioned you can't extend a final class which means base object constructor can't be called. If LLVM is producing a call, then it seems like an ABI bug there.
The test case is in bug #70462. Copying here... g++ -std=c++11 -c -o t.o -x c++ - << EOF struct Bar final { Bar(); }; Bar::Bar() {} EOF $ nm t.o | grep C2 || echo ABI issue
I've not got a reduced example where clang is generating the call, but it could be a linker issue as the two constructors are aliased to the same address. The linker used here was lld.
(In reply to Pádraig Brady from comment #3) > I've not got a reduced example where clang is generating the call, but it > could be a linker issue as the two constructors are aliased to the same > address. > The linker used here was lld. Can you check using BFD LD or gold? And report back? And if it works with them, please file the bug against LLD instead.
i have filed ABI issue 104 https://github.com/itanium-cxx-abi/cxx-abi/issues/104
I think SUSPENDED is more appropriate than WAITING, since we're waiting for an ABI spec clarification.
Richard Smith thinks the ABI is clear and compilers should always emit the as-base ctor. Even though that wording was written before final was a thing. Depends if Jason wants to argue the case?
Let's reopen this then, as GCC needs to keep providing the alias for the base object constructor.
The releases/gcc-10 branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:d94796352234def681a34eef99dad18bccecbca7 commit r10-8659-gd94796352234def681a34eef99dad18bccecbca7 Author: Jason Merrill <jason@redhat.com> Date: Fri Aug 21 16:23:03 2020 -0400 c++: Emit as-base 'tor symbols for final class. [PR95428] For PR70462 I stopped emitting the as-base constructor and destructor variants for final classes, because they can never be called. Except that it turns out that clang calls base variants from complete variants, even for classes with virtual bases, and in some cases inlines them such that the calls to the base variant are exposed. So we need to continue to emit the as-base symbols, even though they're unreachable by G++-compiled code. gcc/cp/ChangeLog: PR c++/95428 * optimize.c (populate_clone_array): Revert PR70462 change. (maybe_clone_body): Likewise. gcc/testsuite/ChangeLog: * g++.dg/other/final8.C: Adjust expected output.
Fixed for 10.3/11.
The master branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:6b958ee0fd0e1b2a2b22784ffbe531ed74358a22 commit r11-2829-g6b958ee0fd0e1b2a2b22784ffbe531ed74358a22 Author: Jason Merrill <jason@redhat.com> Date: Fri Aug 21 16:23:03 2020 -0400 c++: Emit as-base 'tor symbols for final class. [PR95428] For PR70462 I stopped emitting the as-base constructor and destructor variants for final classes, because they can never be called. Except that it turns out that clang calls base variants from complete variants, even for classes with virtual bases, and in some cases inlines them such that the calls to the base variant are exposed. So we need to continue to emit the as-base symbols, even though they're unreachable by G++-compiled code. gcc/cp/ChangeLog: PR c++/95428 * optimize.c (populate_clone_array): Revert PR70462 change. (maybe_clone_body): Likewise. gcc/testsuite/ChangeLog: * g++.dg/other/final8.C: Adjust expected output.