[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