================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits