[clang] [clang] Move two flags from EvalInfo to State (PR #157046)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 5 01:29:26 PDT 2025


https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/157046

Instead of relaying from InterpState to the parent state (which is an EvalInfo), just save the variables in State instead, so both subclasses have access to it.

>From 7049f9e01d0ef3b903e89b5a1516a5839de2da6b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Fri, 5 Sep 2025 10:24:03 +0200
Subject: [PATCH] [clang] Move two flags from EvalInfo to State

Instead of relaying from InterpState to the parent state (which is an
EvalInfo), just save the variables in State instead, so both subclasses
have access to it.
---
 clang/lib/AST/ByteCode/InterpState.cpp | 12 ++++++++++--
 clang/lib/AST/ByteCode/InterpState.h   |  6 ------
 clang/lib/AST/ByteCode/State.h         | 25 +++++++++++++++++++++++--
 clang/lib/AST/ExprConstant.cpp         | 26 --------------------------
 4 files changed, 33 insertions(+), 36 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpState.cpp b/clang/lib/AST/ByteCode/InterpState.cpp
index 4bafb89741857..6b0e72095dc55 100644
--- a/clang/lib/AST/ByteCode/InterpState.cpp
+++ b/clang/lib/AST/ByteCode/InterpState.cpp
@@ -20,13 +20,21 @@ using namespace clang::interp;
 InterpState::InterpState(State &Parent, Program &P, InterpStack &Stk,
                          Context &Ctx, SourceMapper *M)
     : Parent(Parent), M(M), P(P), Stk(Stk), Ctx(Ctx), BottomFrame(*this),
-      Current(&BottomFrame) {}
+      Current(&BottomFrame) {
+  CheckingPotentialConstantExpression =
+      Parent.CheckingPotentialConstantExpression;
+  CheckingForUndefinedBehavior = Parent.CheckingForUndefinedBehavior;
+}
 
 InterpState::InterpState(State &Parent, Program &P, InterpStack &Stk,
                          Context &Ctx, const Function *Func)
     : Parent(Parent), M(nullptr), P(P), Stk(Stk), Ctx(Ctx),
       BottomFrame(*this, Func, nullptr, CodePtr(), Func->getArgSize()),
-      Current(&BottomFrame) {}
+      Current(&BottomFrame) {
+  CheckingPotentialConstantExpression =
+      Parent.CheckingPotentialConstantExpression;
+  CheckingForUndefinedBehavior = Parent.CheckingForUndefinedBehavior;
+}
 
 bool InterpState::inConstantContext() const {
   if (ConstantContextOverride)
diff --git a/clang/lib/AST/ByteCode/InterpState.h b/clang/lib/AST/ByteCode/InterpState.h
index 1e4c0701723c6..e4d1dc64ff01b 100644
--- a/clang/lib/AST/ByteCode/InterpState.h
+++ b/clang/lib/AST/ByteCode/InterpState.h
@@ -70,18 +70,12 @@ class InterpState final : public State, public SourceMapper {
   ASTContext &getASTContext() const override { return Parent.getASTContext(); }
 
   // Forward status checks and updates to the walker.
-  bool checkingForUndefinedBehavior() const override {
-    return Parent.checkingForUndefinedBehavior();
-  }
   bool keepEvaluatingAfterFailure() const override {
     return Parent.keepEvaluatingAfterFailure();
   }
   bool keepEvaluatingAfterSideEffect() const override {
     return Parent.keepEvaluatingAfterSideEffect();
   }
-  bool checkingPotentialConstantExpression() const override {
-    return Parent.checkingPotentialConstantExpression();
-  }
   bool noteUndefinedBehavior() override {
     return Parent.noteUndefinedBehavior();
   }
diff --git a/clang/lib/AST/ByteCode/State.h b/clang/lib/AST/ByteCode/State.h
index 6fc33222ac956..387ce396a7235 100644
--- a/clang/lib/AST/ByteCode/State.h
+++ b/clang/lib/AST/ByteCode/State.h
@@ -59,8 +59,6 @@ class State {
 public:
   virtual ~State();
 
-  virtual bool checkingForUndefinedBehavior() const = 0;
-  virtual bool checkingPotentialConstantExpression() const = 0;
   virtual bool noteUndefinedBehavior() = 0;
   virtual bool keepEvaluatingAfterFailure() const = 0;
   virtual bool keepEvaluatingAfterSideEffect() const = 0;
@@ -75,6 +73,16 @@ class State {
   virtual unsigned getCallStackDepth() = 0;
   virtual bool noteSideEffect() = 0;
 
+  /// Are we checking whether the expression is a potential constant
+  /// expression?
+  bool checkingPotentialConstantExpression() const {
+    return CheckingPotentialConstantExpression;
+  }
+  /// Are we checking an expression for overflow?
+  bool checkingForUndefinedBehavior() const {
+    return CheckingForUndefinedBehavior;
+  }
+
 public:
   State() = default;
   /// Diagnose that the evaluation could not be folded (FF => FoldFailure)
@@ -128,6 +136,19 @@ class State {
   /// constant value.
   bool InConstantContext = false;
 
+  /// Whether we're checking that an expression is a potential constant
+  /// expression. If so, do not fail on constructs that could become constant
+  /// later on (such as a use of an undefined global).
+  bool CheckingPotentialConstantExpression = false;
+
+  /// Whether we're checking for an expression that has undefined behavior.
+  /// If so, we will produce warnings if we encounter an operation that is
+  /// always undefined.
+  ///
+  /// Note that we still need to evaluate the expression normally when this
+  /// is set; this is used when evaluating ICEs in C.
+  bool CheckingForUndefinedBehavior = false;
+
 private:
   void addCallStack(unsigned Limit);
 
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 66362d44976c4..10019cd956899 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -926,19 +926,6 @@ namespace {
     /// fold (not just why it's not strictly a constant expression)?
     bool HasFoldFailureDiagnostic;
 
-    /// Whether we're checking that an expression is a potential constant
-    /// expression. If so, do not fail on constructs that could become constant
-    /// later on (such as a use of an undefined global).
-    bool CheckingPotentialConstantExpression = false;
-
-    /// Whether we're checking for an expression that has undefined behavior.
-    /// If so, we will produce warnings if we encounter an operation that is
-    /// always undefined.
-    ///
-    /// Note that we still need to evaluate the expression normally when this
-    /// is set; this is used when evaluating ICEs in C.
-    bool CheckingForUndefinedBehavior = false;
-
     enum EvaluationMode {
       /// Evaluate as a constant expression. Stop if we find that the expression
       /// is not a constant expression.
@@ -960,19 +947,6 @@ namespace {
       EM_IgnoreSideEffects,
     } EvalMode;
 
-    /// Are we checking whether the expression is a potential constant
-    /// expression?
-    bool checkingPotentialConstantExpression() const override  {
-      return CheckingPotentialConstantExpression;
-    }
-
-    /// Are we checking an expression for overflow?
-    // FIXME: We should check for any kind of undefined or suspicious behavior
-    // in such constructs, not just overflow.
-    bool checkingForUndefinedBehavior() const override {
-      return CheckingForUndefinedBehavior;
-    }
-
     EvalInfo(const ASTContext &C, Expr::EvalStatus &S, EvaluationMode Mode)
         : Ctx(const_cast<ASTContext &>(C)), EvalStatus(S), CurrentCall(nullptr),
           CallStackDepth(0), NextCallIndex(1),



More information about the cfe-commits mailing list