Bug 95428 - ABI breakage for "base object constructor" for final classes
Summary: ABI breakage for "base object constructor" for final classes
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: 10.3
Assignee: Jason Merrill
URL:
Keywords: ABI
Depends on: 70462
Blocks:
  Show dependency treegraph
 
Reported: 2020-05-30 00:08 UTC by Pádraig Brady
Modified: 2020-08-25 02:44 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-05-31 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Pádraig Brady 2020-05-30 00:08:51 UTC
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
Comment 1 Andrew Pinski 2020-05-30 23:56:17 UTC
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.
Comment 2 Pádraig Brady 2020-05-31 12:31:26 UTC
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
Comment 3 Pádraig Brady 2020-05-31 12:46:18 UTC
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.
Comment 4 Andrew Pinski 2020-05-31 16:46:03 UTC
(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.
Comment 5 Nathan Sidwell 2020-06-01 13:29:05 UTC
i have filed ABI issue 104 https://github.com/itanium-cxx-abi/cxx-abi/issues/104
Comment 6 Jonathan Wakely 2020-06-04 09:47:03 UTC
I think SUSPENDED is more appropriate than WAITING, since we're waiting for an ABI spec clarification.
Comment 7 Nathan Sidwell 2020-06-05 20:15:58 UTC
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?
Comment 8 Jonathan Wakely 2020-08-21 09:45:50 UTC
Let's reopen this then, as GCC needs to keep providing the alias for the base object constructor.
Comment 9 GCC Commits 2020-08-24 21:44:32 UTC
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.
Comment 10 Jason Merrill 2020-08-24 21:47:21 UTC
Fixed for 10.3/11.
Comment 11 GCC Commits 2020-08-25 02:44:01 UTC
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.