https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117913
Bug ID: 117913
Summary: destroying delete operator should have implicit
expection speciification
Product: gcc
Version: 15.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: alisdairm at me dot com
Target Milestone: ---
According to [except.spec] 14.5p9, "A deallocation function (6.7.6.5.3) with no
explicit noexcept-specifier has a non-throwing exception specification."
According to the xref (6.7.6.5.3), destroying delete is a deallocation
function, so should have an implicit `noexcept(true)` where no exception
specification is provided.
The following test program verifies all permutations, and gcc fails for only
the case of the implicit exception specification.
Note that when there is a destroying delete, the destructor for the class is
*not* called as part of the delete expression, so the throwing destructor in
the example is there to confirm other behavior that GCC handles correctly.
#include <cstdio>
#include <new>
struct Implicit {
~Implicit() noexcept(false) {}
void operator delete(Implicit*, std::destroying_delete_t) {
std::puts("destroyed implicit");
}
};
struct Explicit {
~Explicit() noexcept(false) {}
void operator delete(Explicit*, std::destroying_delete_t) noexcept {
std::puts("destroyed explicit");
}
};
struct Undefined {
~Undefined() noexcept(false) {}
void operator delete(Undefined*, std::destroying_delete_t) noexcept(false)
{
std::puts("destroyed UB");
throw 42;
}
};
Implicit * pn = nullptr;
static_assert( noexcept(delete(pn)));
Explicit * qn = nullptr;
static_assert( noexcept(delete(qn)));
Undefined * un = nullptr;
static_assert(!noexcept(delete(un)));
int main() {
Implicit *p = new Implicit();
delete p;
Explicit *q = new Explicit();
delete q;
try {
Undefined *u = new Undefined();
delete u;
}
catch (...) {
std::puts("undefined behavior");
}
}