Bug 93413 - Defaulted constexpr Destructor not being found during constant evaluation
Summary: Defaulted constexpr Destructor not being found during constant evaluation
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: 13.0
Assignee: Patrick Palka
URL:
Keywords: rejects-valid
: 96614 99495 104653 105846 106287 107512 (view as bug list)
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2020-01-24 13:00 UTC by Antony Polukhin
Modified: 2022-11-03 19:11 UTC (History)
11 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-01-24 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Antony Polukhin 2020-01-24 13:00:59 UTC
Consider the example:


struct Base {
    constexpr virtual ~Base(){}
};

struct Derived: Base {};

constexpr Derived d;


Destructor for the `Derived` should be implicitly defined. However the above snippet produces error message on GCC-10 with -std=c++2a flag: `error: 'virtual constexpr Derived::~Derived()' used before its definition`.
Comment 1 Jakub Jelinek 2020-01-24 22:02:31 UTC
Seems to be dup of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92695#c12
I'm afraid I don't know how to resolve this.
Comment 2 Luke Dalessandro 2021-04-24 02:39:12 UTC
I just ran into this today. The referenced "dup" seems to have been resolved last June, but this is still failing. Also probably the same as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99495.

Is there any chance someone could take a fresh look at this?
Comment 3 Andrew Pinski 2021-08-17 05:56:15 UTC
*** Bug 96614 has been marked as a duplicate of this bug. ***
Comment 4 Andrew Pinski 2021-08-17 05:57:32 UTC
*** Bug 99495 has been marked as a duplicate of this bug. ***
Comment 5 Andrew Pinski 2021-08-17 05:58:31 UTC
The problem is the default Destructor in the Derived for the other examples.
So this can be reduced to just:
struct Base
{
    constexpr virtual ~Base() = default;
};

constexpr Base b;
Comment 6 Andrew Pinski 2022-02-23 07:46:02 UTC
*** Bug 104653 has been marked as a duplicate of this bug. ***
Comment 7 Andrew Pinski 2022-07-13 22:44:50 UTC
*** Bug 106287 has been marked as a duplicate of this bug. ***
Comment 8 Andrew Pinski 2022-07-13 22:45:21 UTC
*** Bug 105846 has been marked as a duplicate of this bug. ***
Comment 9 Andrew Pinski 2022-11-02 20:39:57 UTC
*** Bug 107512 has been marked as a duplicate of this bug. ***
Comment 10 GCC Commits 2022-11-03 18:56:33 UTC
The master branch has been updated by Patrick Palka <ppalka@gcc.gnu.org>:

https://gcc.gnu.org/g:c0b38e9fec71dc4cc5e99b1f0cb159c15a8da9ba

commit r13-3638-gc0b38e9fec71dc4cc5e99b1f0cb159c15a8da9ba
Author: Patrick Palka <ppalka@redhat.com>
Date:   Thu Nov 3 14:55:35 2022 -0400

    c++: constexpr error with defaulted virtual dtor [PR93413]
    
    We're rejecting the below testcase with
    
      error: 'virtual constexpr Base::~Base()' used before its definition
      error: 'virtual constexpr Derived::~Derived()' used before its definition
    
    due to special handling in mark_used added by r181272 to defer synthesis
    of virtual destructors until EOF (where we can set their linkage), which
    in turn makes them effectively unusable during constexpr evaluation.
    
    Fortunately it seems this special handling is unnecessary ever since
    r208030 enabled us to tentatively set linkage of all defaulted virtual
    destructors, including templated ones.  So this patch gets rid of this
    special handling.
    
            PR c++/93413
    
    gcc/cp/ChangeLog:
    
            * decl2.cc (mark_used): Don't defer synthesis of virtual
            functions.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/constexpr-virtual21.C: New test.
Comment 11 Patrick Palka 2022-11-03 19:11:44 UTC
Fixed for GCC 13.  The fix is probably unsuitable for backporting, and there are workarounds anyway -- one workaround is to turn the problematic class into a class template with an explicitly defaulted dtor, e.g. for the original testcase do:

struct Base {
    constexpr virtual ~Base(){}
};

template<class=void>
struct Derived: Base {
  ~Derived() = default;
};

constexpr Derived<> d;