[clang] [C++20] Destroying delete and deleted destructors (PR #118800)
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 5 11:30:44 PST 2024
================
@@ -3768,6 +3768,28 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
ArrayForm ? OO_Array_Delete : OO_Delete);
+ // C++20 [expr.delete]p6: If the value of the operand of the delete-
+ // expression is not a null pointer value and the selected deallocation
+ // function (see below) is not a destroying operator delete, the delete-
+ // expression will invoke the destructor (if any) for the object or the
+ // elements of the array being deleted.
+ //
+ // This means we should not look at the destructor for a destroying
+ // delete operator, as that destructor is never called, unless the
+ // destructor is virtual (see [expr.delete]p8.1) because then the
+ // selected operator depends on the dynamic type of the pointer.
----------------
zygoloid wrote:
Oh no! In the converse of this case it seems like we simply have no idea if the delete expression is potentially throwing. Eg, given:
```c++
struct A {
virtual ~A(); // implicitly noexcept
};
struct B : A {
void operator delete(B *p, std::destroying_delete_t) { throw "oh no"; }
};
A *p = new B;
static_assert(noexcept(delete p));
```
the assert doesn't fire but `delete p` can throw.
But there's nothing specific to a destroying delete here. We have the same problem with a normal class-specific delete:
```c++
struct C : A {
void operator delete(void*) { throw "oops"; }
};
A *q = new C;
static_assert(noexcept(delete q));
```
I think this is a language defect; [mailed to CWG for consideration](https://lists.isocpp.org/core/2024/12/16576.php).
https://github.com/llvm/llvm-project/pull/118800
More information about the cfe-commits
mailing list