[clang] 18d2ff4 - [clang][Interp] Allow recursive intepretation

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 1 06:30:32 PST 2024


Author: Timm Bäder
Date: 2024-03-01T15:28:14+01:00
New Revision: 18d2ff4be7898eaf666564dcca07ad6bd38ababf

URL: https://github.com/llvm/llvm-project/commit/18d2ff4be7898eaf666564dcca07ad6bd38ababf
DIFF: https://github.com/llvm/llvm-project/commit/18d2ff4be7898eaf666564dcca07ad6bd38ababf.diff

LOG: [clang][Interp] Allow recursive intepretation

This shouldn't be a problem in general, but we used to have some
sanity checks that prevented it from working. Remove those and
only do them on the non-recursive calls instead.

Added: 
    

Modified: 
    clang/lib/AST/Interp/Context.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp
index b09019f3e65b79..0cec0d78326bd6 100644
--- a/clang/lib/AST/Interp/Context.cpp
+++ b/clang/lib/AST/Interp/Context.cpp
@@ -41,7 +41,7 @@ bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) {
 }
 
 bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) {
-  assert(Stk.empty());
+  bool Recursing = !Stk.empty();
   ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result);
 
   auto Res = C.interpretExpr(E, /*ConvertResultToRValue=*/E->isGLValue());
@@ -51,12 +51,14 @@ bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) {
     return false;
   }
 
-  assert(Stk.empty());
+  if (!Recursing) {
+    assert(Stk.empty());
 #ifndef NDEBUG
-  // Make sure we don't rely on some value being still alive in
-  // InterpStack memory.
-  Stk.clear();
+    // Make sure we don't rely on some value being still alive in
+    // InterpStack memory.
+    Stk.clear();
 #endif
+  }
 
   Result = Res.toAPValue();
 
@@ -64,7 +66,7 @@ bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) {
 }
 
 bool Context::evaluate(State &Parent, const Expr *E, APValue &Result) {
-  assert(Stk.empty());
+  bool Recursing = !Stk.empty();
   ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result);
 
   auto Res = C.interpretExpr(E);
@@ -73,19 +75,22 @@ bool Context::evaluate(State &Parent, const Expr *E, APValue &Result) {
     return false;
   }
 
-  assert(Stk.empty());
+  if (!Recursing) {
+    assert(Stk.empty());
 #ifndef NDEBUG
-  // Make sure we don't rely on some value being still alive in
-  // InterpStack memory.
-  Stk.clear();
+    // Make sure we don't rely on some value being still alive in
+    // InterpStack memory.
+    Stk.clear();
 #endif
+  }
+
   Result = Res.toAPValue();
   return true;
 }
 
 bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD,
                                     APValue &Result) {
-  assert(Stk.empty());
+  bool Recursing = !Stk.empty();
   ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result);
 
   bool CheckGlobalInitialized =
@@ -97,12 +102,14 @@ bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD,
     return false;
   }
 
-  assert(Stk.empty());
+  if (!Recursing) {
+    assert(Stk.empty());
 #ifndef NDEBUG
-  // Make sure we don't rely on some value being still alive in
-  // InterpStack memory.
-  Stk.clear();
+    // Make sure we don't rely on some value being still alive in
+    // InterpStack memory.
+    Stk.clear();
 #endif
+  }
 
   Result = Res.toAPValue();
   return true;


        


More information about the cfe-commits mailing list