[clang] b22adf0 - [clang][Interp] Clear pointers pointing to dead blocks
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Sat Jul 13 06:59:43 PDT 2024
Author: Timm Bäder
Date: 2024-07-13T15:55:55+02:00
New Revision: b22adf02a2d2cc290d618fe47bec5aeec47ab992
URL: https://github.com/llvm/llvm-project/commit/b22adf02a2d2cc290d618fe47bec5aeec47ab992
DIFF: https://github.com/llvm/llvm-project/commit/b22adf02a2d2cc290d618fe47bec5aeec47ab992.diff
LOG: [clang][Interp] Clear pointers pointing to dead blocks
before free()ing the dead blocks. Otherwise, we might end up with
dangling Pointers to those dead blocks.
Added:
Modified:
clang/lib/AST/Interp/InterpState.cpp
clang/lib/AST/Interp/Pointer.h
clang/test/AST/Interp/lifetimes.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/InterpState.cpp b/clang/lib/AST/Interp/InterpState.cpp
index 550bc9f1a84b..a8538541f491 100644
--- a/clang/lib/AST/Interp/InterpState.cpp
+++ b/clang/lib/AST/Interp/InterpState.cpp
@@ -33,7 +33,15 @@ InterpState::~InterpState() {
}
}
-void InterpState::cleanup() {}
+void InterpState::cleanup() {
+ // As a last resort, make sure all pointers still pointing to a dead block
+ // don't point to it anymore.
+ for (DeadBlock *DB = DeadBlocks; DB; DB = DB->Next) {
+ for (Pointer *P = DB->B.Pointers; P; P = P->Next) {
+ P->PointeeStorage.BS.Pointee = nullptr;
+ }
+ }
+}
Frame *InterpState::getCurrentFrame() {
if (Current && Current->Caller)
diff --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h
index 3515f525a22f..6e9e8675306e 100644
--- a/clang/lib/AST/Interp/Pointer.h
+++ b/clang/lib/AST/Interp/Pointer.h
@@ -635,6 +635,7 @@ class Pointer {
friend class Block;
friend class DeadBlock;
friend class MemberPointer;
+ friend class InterpState;
friend struct InitMap;
Pointer(Block *Pointee, unsigned Base, uint64_t Offset);
diff --git a/clang/test/AST/Interp/lifetimes.cpp b/clang/test/AST/Interp/lifetimes.cpp
index c544baba6178..d47533ab547b 100644
--- a/clang/test/AST/Interp/lifetimes.cpp
+++ b/clang/test/AST/Interp/lifetimes.cpp
@@ -1,6 +1,8 @@
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s
// RUN: %clang_cc1 -verify=ref,both %s
+/// FIXME: Slight
diff erence in diagnostic output here.
+
struct Foo {
int a;
};
@@ -20,3 +22,14 @@ static_assert(dead1() == 1, ""); // both-error {{not an integral constant expres
// both-note {{in call to}}
+struct S {
+ int &&r; // both-note {{reference member declared here}}
+ int t;
+ constexpr S() : r(0), t(r) {} // both-error {{reference member 'r' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}} \
+ // ref-note {{read of object outside its lifetime is not allowed in a constant expression}} \
+ // expected-note {{temporary created here}} \
+ // expected-note {{read of temporary whose lifetime has ended}}
+};
+constexpr int k1 = S().t; // both-error {{must be initialized by a constant expression}} \
+ // ref-note {{in call to}} \
+ // expected-note {{in call to}}
More information about the cfe-commits
mailing list