diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 5e0d2e91fb1b2..67b7ac1f8f0f9 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -992,7 +992,8 @@ static bool runRecordDestructor(InterpState &S, CodePtr OpPC, const Record *R = Desc->ElemRecord; assert(R); - if (Pointer::pointToSameBlock(BasePtr, S.Current->getThis())) { + if (Pointer::pointToSameBlock(BasePtr, S.Current->getThis()) && + S.Current->getFunction()->isDestructor()) { const SourceInfo &Loc = S.Current->getSource(OpPC); S.FFDiag(Loc, diag::note_constexpr_double_destroy); return false; diff --git a/clang/test/AST/ByteCode/new-delete.cpp b/clang/test/AST/ByteCode/new-delete.cpp index a85ddaf29caf4..bd7351cbc3d4c 100644 --- a/clang/test/AST/ByteCode/new-delete.cpp +++ b/clang/test/AST/ByteCode/new-delete.cpp @@ -558,6 +558,11 @@ namespace DeleteThis { } static_assert(super_secret_double_delete()); // both-error {{not an integral constant expression}} \ // both-note {{in call to 'super_secret_double_delete()'}} + + struct B { + constexpr void reset() { delete this; } + }; + static_assert(((new B)->reset(), true)); } namespace CastedDelete {