Author: rsmith Date: Sun Oct 6 20:14:28 2019 New Revision: 373875 URL: http://llvm.org/viewvc/llvm-project?rev=373875&view=rev Log: [c++20] Check for a class-specific operator delete when deleting an object of class type with a virtual destructor.
Modified: cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp Modified: cfe/trunk/lib/AST/ExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=373875&r1=373874&r2=373875&view=diff ============================================================================== --- cfe/trunk/lib/AST/ExprConstant.cpp (original) +++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Oct 6 20:14:28 2019 @@ -6019,6 +6019,13 @@ static bool hasVirtualDestructor(QualTyp return false; } +static const FunctionDecl *getVirtualOperatorDelete(QualType T) { + if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) + if (CXXDestructorDecl *DD = RD->getDestructor()) + return DD->isVirtual() ? DD->getOperatorDelete() : nullptr; + return nullptr; +} + /// Check that the given object is a suitable pointer to a heap allocation that /// still exists and is of the right kind for the purpose of a deletion. /// @@ -13208,6 +13215,18 @@ bool VoidExprEvaluator::VisitCXXDeleteEx return false; } + // For a class type with a virtual destructor, the selected operator delete + // is the one looked up when building the destructor. + if (!E->isArrayForm() && !E->isGlobalDelete()) { + const FunctionDecl *VirtualDelete = getVirtualOperatorDelete(AllocType); + if (VirtualDelete && + !VirtualDelete->isReplaceableGlobalAllocationFunction()) { + Info.FFDiag(E, diag::note_constexpr_new_non_replaceable) + << isa<CXXMethodDecl>(VirtualDelete) << VirtualDelete; + return false; + } + } + if (!HandleDestruction(Info, E->getExprLoc(), Pointer.getLValueBase(), (*Alloc)->Value, AllocType)) return false; Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp?rev=373875&r1=373874&r2=373875&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp (original) +++ cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp Sun Oct 6 20:14:28 2019 @@ -1190,6 +1190,25 @@ namespace dtor_call { static_assert(virt_dtor(3, "YX")); static_assert(virt_dtor(4, "X")); + constexpr bool virt_delete(bool global) { + struct A { + virtual constexpr ~A() {} + }; + struct B : A { + void operator delete(void *); + constexpr ~B() {} + }; + + A *p = new B; + if (global) + ::delete p; + else + delete p; // expected-note {{call to class-specific 'operator delete'}} + return true; + } + static_assert(virt_delete(true)); + static_assert(virt_delete(false)); // expected-error {{}} expected-note {{in call}} + constexpr void use_after_virt_destroy() { char buff[4] = {}; VU vu; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits