https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/101792
None >From 08aaea88863ad000d68316391a8702cd777496af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Sat, 3 Aug 2024 06:37:24 +0200 Subject: [PATCH] [clang][Interp] Check for 'delete this' in dtors --- clang/lib/AST/Interp/Interp.cpp | 6 ++++++ clang/lib/AST/Interp/Pointer.cpp | 6 ++++++ clang/lib/AST/Interp/Pointer.h | 2 ++ clang/test/AST/Interp/new-delete.cpp | 13 +++++++++++++ 4 files changed, 27 insertions(+) diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index 9009cf820244d..0252dd0d32699 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -836,6 +836,12 @@ static bool runRecordDestructor(InterpState &S, CodePtr OpPC, const Record *R = Desc->ElemRecord; assert(R); + if (Pointer::pointToSameBlock(BasePtr, S.Current->getThis())) { + const SourceInfo &Loc = S.Current->getSource(OpPC); + S.FFDiag(Loc, diag::note_constexpr_double_destroy); + return false; + } + // Fields. for (const Record::Field &Field : llvm::reverse(R->fields())) { const Descriptor *D = Field.Desc; diff --git a/clang/lib/AST/Interp/Pointer.cpp b/clang/lib/AST/Interp/Pointer.cpp index 79fe317a61dff..f86be1214826d 100644 --- a/clang/lib/AST/Interp/Pointer.cpp +++ b/clang/lib/AST/Interp/Pointer.cpp @@ -398,6 +398,12 @@ bool Pointer::hasSameBase(const Pointer &A, const Pointer &B) { return A.asBlockPointer().Pointee == B.asBlockPointer().Pointee; } +bool Pointer::pointToSameBlock(const Pointer &A, const Pointer &B) { + if (!A.isBlockPointer() || !B.isBlockPointer()) + return false; + return A.block() == B.block(); +} + bool Pointer::hasSameArray(const Pointer &A, const Pointer &B) { return hasSameBase(A, B) && A.PointeeStorage.BS.Base == B.PointeeStorage.BS.Base && diff --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h index 6b0c31358159c..6f6983458ab60 100644 --- a/clang/lib/AST/Interp/Pointer.h +++ b/clang/lib/AST/Interp/Pointer.h @@ -665,6 +665,8 @@ class Pointer { static bool hasSameBase(const Pointer &A, const Pointer &B); /// Checks if two pointers can be subtracted. static bool hasSameArray(const Pointer &A, const Pointer &B); + /// Checks if both given pointers point to the same block. + static bool pointToSameBlock(const Pointer &A, const Pointer &B); /// Prints the pointer. void print(llvm::raw_ostream &OS) const; diff --git a/clang/test/AST/Interp/new-delete.cpp b/clang/test/AST/Interp/new-delete.cpp index 7a85def784920..ae76950f13731 100644 --- a/clang/test/AST/Interp/new-delete.cpp +++ b/clang/test/AST/Interp/new-delete.cpp @@ -551,6 +551,19 @@ namespace FaultyDtorCalledByDelete { // both-note {{in call to 'abc()'}} } +namespace DeleteThis { + constexpr bool super_secret_double_delete() { + struct A { + constexpr ~A() { delete this; } // both-note {{destruction of object that is already being destroyed}} \ + // ref-note {{in call to}} + }; + delete new A; // both-note {{in call to}} + return true; + } + static_assert(super_secret_double_delete()); // both-error {{not an integral constant expression}} \ + // both-note {{in call to 'super_secret_double_delete()'}} +} + #else /// Make sure we reject this prior to C++20 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits