[clang] [clang][Interp] Check for 'delete this' in dtors (PR #101792)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 2 21:48:04 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/101792.diff
4 Files Affected:
- (modified) clang/lib/AST/Interp/Interp.cpp (+6)
- (modified) clang/lib/AST/Interp/Pointer.cpp (+6)
- (modified) clang/lib/AST/Interp/Pointer.h (+2)
- (modified) clang/test/AST/Interp/new-delete.cpp (+13)
``````````diff
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/101792
More information about the cfe-commits
mailing list