https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/177738

>From b5a702ece74dd1f53ebbb3d74497b5bb788fc081 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]>
Date: Fri, 23 Jan 2026 14:29:38 +0100
Subject: [PATCH] State

---
 clang/lib/AST/ByteCode/InterpState.cpp |  13 ++-
 clang/lib/AST/ByteCode/InterpState.h   |  37 +------
 clang/lib/AST/ByteCode/State.cpp       |  74 ++++++++++---
 clang/lib/AST/ByteCode/State.h         |  84 +++++++++++---
 clang/lib/AST/ExprConstant.cpp         | 145 +++----------------------
 5 files changed, 156 insertions(+), 197 deletions(-)

diff --git a/clang/lib/AST/ByteCode/InterpState.cpp 
b/clang/lib/AST/ByteCode/InterpState.cpp
index a95916cd63981..837d5fef91b8e 100644
--- a/clang/lib/AST/ByteCode/InterpState.cpp
+++ b/clang/lib/AST/ByteCode/InterpState.cpp
@@ -17,10 +17,10 @@
 using namespace clang;
 using namespace clang::interp;
 
-InterpState::InterpState(State &Parent, Program &P, InterpStack &Stk,
+InterpState::InterpState(const State &Parent, Program &P, InterpStack &Stk,
                          Context &Ctx, SourceMapper *M)
-    : Parent(Parent), M(M), P(P), Stk(Stk), Ctx(Ctx), BottomFrame(*this),
-      Current(&BottomFrame) {
+    : State(Ctx.getASTContext(), Parent.getEvalStatus()), M(M), P(P), Stk(Stk),
+      Ctx(Ctx), BottomFrame(*this), Current(&BottomFrame) {
   InConstantContext = Parent.InConstantContext;
   CheckingPotentialConstantExpression =
       Parent.CheckingPotentialConstantExpression;
@@ -28,9 +28,10 @@ InterpState::InterpState(State &Parent, Program &P, 
InterpStack &Stk,
   EvalMode = Parent.EvalMode;
 }
 
-InterpState::InterpState(State &Parent, Program &P, InterpStack &Stk,
+InterpState::InterpState(const State &Parent, Program &P, InterpStack &Stk,
                          Context &Ctx, const Function *Func)
-    : Parent(Parent), M(nullptr), P(P), Stk(Stk), Ctx(Ctx),
+    : State(Ctx.getASTContext(), Parent.getEvalStatus()), M(nullptr), P(P),
+      Stk(Stk), Ctx(Ctx),
       BottomFrame(*this, Func, nullptr, CodePtr(), Func->getArgSize()),
       Current(&BottomFrame) {
   InConstantContext = Parent.InConstantContext;
@@ -75,7 +76,7 @@ void InterpState::cleanup() {
     Alloc->cleanup();
 }
 
-Frame *InterpState::getCurrentFrame() { return Current; }
+const Frame *InterpState::getCurrentFrame() { return Current; }
 
 void InterpState::deallocate(Block *B) {
   assert(B);
diff --git a/clang/lib/AST/ByteCode/InterpState.h 
b/clang/lib/AST/ByteCode/InterpState.h
index 231b51124c70d..98dc5cfd3b3c4 100644
--- a/clang/lib/AST/ByteCode/InterpState.h
+++ b/clang/lib/AST/ByteCode/InterpState.h
@@ -35,9 +35,9 @@ struct StdAllocatorCaller {
 /// Interpreter context.
 class InterpState final : public State, public SourceMapper {
 public:
-  InterpState(State &Parent, Program &P, InterpStack &Stk, Context &Ctx,
+  InterpState(const State &Parent, Program &P, InterpStack &Stk, Context &Ctx,
               SourceMapper *M = nullptr);
-  InterpState(State &Parent, Program &P, InterpStack &Stk, Context &Ctx,
+  InterpState(const State &Parent, Program &P, InterpStack &Stk, Context &Ctx,
               const Function *Func);
 
   ~InterpState();
@@ -50,41 +50,14 @@ class InterpState final : public State, public SourceMapper 
{
   bool diagnosing() const { return getEvalStatus().Diag != nullptr; }
 
   // Stack frame accessors.
-  Frame *getCurrentFrame() override;
+  const Frame *getCurrentFrame() override;
   unsigned getCallStackDepth() override {
     return Current ? (Current->getDepth() + 1) : 1;
   }
   const Frame *getBottomFrame() const override { return &BottomFrame; }
 
-  // Access objects from the walker context.
-  Expr::EvalStatus &getEvalStatus() const override {
-    return Parent.getEvalStatus();
-  }
-  ASTContext &getASTContext() const override { return Ctx.getASTContext(); }
-  const LangOptions &getLangOpts() const {
-    return Ctx.getASTContext().getLangOpts();
-  }
-
-  // Forward status checks and updates to the walker.
-  bool keepEvaluatingAfterFailure() const override {
-    return Parent.keepEvaluatingAfterFailure();
-  }
-  bool keepEvaluatingAfterSideEffect() const override {
-    return Parent.keepEvaluatingAfterSideEffect();
-  }
-  bool noteUndefinedBehavior() override {
-    return Parent.noteUndefinedBehavior();
-  }
+  bool stepsLeft() const override { return true; }
   bool inConstantContext() const;
-  bool hasActiveDiagnostic() override { return Parent.hasActiveDiagnostic(); }
-  void setActiveDiagnostic(bool Flag) override {
-    Parent.setActiveDiagnostic(Flag);
-  }
-  void setFoldFailureDiagnostic(bool Flag) override {
-    Parent.setFoldFailureDiagnostic(Flag);
-  }
-  bool hasPriorDiagnostic() override { return Parent.hasPriorDiagnostic(); }
-  bool noteSideEffect() override { return Parent.noteSideEffect(); }
 
   /// Deallocates a pointer.
   void deallocate(Block *B);
@@ -149,8 +122,6 @@ class InterpState final : public State, public SourceMapper 
{
 private:
   friend class EvaluationResult;
   friend class InterpStateCCOverride;
-  /// AST Walker state.
-  State &Parent;
   /// Dead block chain.
   DeadBlock *DeadBlocks = nullptr;
   /// Reference to the offset-source mapping.
diff --git a/clang/lib/AST/ByteCode/State.cpp b/clang/lib/AST/ByteCode/State.cpp
index 323231fbf8236..f1192f1d07ebd 100644
--- a/clang/lib/AST/ByteCode/State.cpp
+++ b/clang/lib/AST/ByteCode/State.cpp
@@ -25,15 +25,15 @@ OptionalDiagnostic State::FFDiag(SourceLocation Loc, 
diag::kind DiagId,
 
 OptionalDiagnostic State::FFDiag(const Expr *E, diag::kind DiagId,
                                  unsigned ExtraNotes) {
-  if (getEvalStatus().Diag)
+  if (EvalStatus.Diag)
     return diag(E->getExprLoc(), DiagId, ExtraNotes, false);
   setActiveDiagnostic(false);
   return OptionalDiagnostic();
 }
 
-OptionalDiagnostic State::FFDiag(const SourceInfo &SI, diag::kind DiagId,
+OptionalDiagnostic State::FFDiag(SourceInfo SI, diag::kind DiagId,
                                  unsigned ExtraNotes) {
-  if (getEvalStatus().Diag)
+  if (EvalStatus.Diag)
     return diag(SI.getLoc(), DiagId, ExtraNotes, false);
   setActiveDiagnostic(false);
   return OptionalDiagnostic();
@@ -43,7 +43,7 @@ OptionalDiagnostic State::CCEDiag(SourceLocation Loc, 
diag::kind DiagId,
                                   unsigned ExtraNotes) {
   // Don't override a previous diagnostic. Don't bother collecting
   // diagnostics if we're evaluating for overflow.
-  if (!getEvalStatus().Diag || !getEvalStatus().Diag->empty()) {
+  if (!EvalStatus.Diag || !EvalStatus.Diag->empty()) {
     setActiveDiagnostic(false);
     return OptionalDiagnostic();
   }
@@ -55,7 +55,7 @@ OptionalDiagnostic State::CCEDiag(const Expr *E, diag::kind 
DiagId,
   return CCEDiag(E->getExprLoc(), DiagId, ExtraNotes);
 }
 
-OptionalDiagnostic State::CCEDiag(const SourceInfo &SI, diag::kind DiagId,
+OptionalDiagnostic State::CCEDiag(SourceInfo SI, diag::kind DiagId,
                                   unsigned ExtraNotes) {
   return CCEDiag(SI.getLoc(), DiagId, ExtraNotes);
 }
@@ -68,31 +68,29 @@ OptionalDiagnostic State::Note(SourceLocation Loc, 
diag::kind DiagId) {
 
 void State::addNotes(ArrayRef<PartialDiagnosticAt> Diags) {
   if (hasActiveDiagnostic())
-    llvm::append_range(*getEvalStatus().Diag, Diags);
+    llvm::append_range(*EvalStatus.Diag, Diags);
 }
 
 DiagnosticBuilder State::report(SourceLocation Loc, diag::kind DiagId) {
-  return getASTContext().getDiagnostics().Report(Loc, DiagId);
+  return Ctx.getDiagnostics().Report(Loc, DiagId);
 }
 
 /// Add a diagnostic to the diagnostics list.
 PartialDiagnostic &State::addDiag(SourceLocation Loc, diag::kind DiagId) {
-  PartialDiagnostic PD(DiagId, getASTContext().getDiagAllocator());
-  getEvalStatus().Diag->push_back(std::make_pair(Loc, PD));
-  return getEvalStatus().Diag->back().second;
+  PartialDiagnostic PD(DiagId, Ctx.getDiagAllocator());
+  EvalStatus.Diag->push_back(std::make_pair(Loc, PD));
+  return EvalStatus.Diag->back().second;
 }
 
 OptionalDiagnostic State::diag(SourceLocation Loc, diag::kind DiagId,
                                unsigned ExtraNotes, bool IsCCEDiag) {
-  Expr::EvalStatus &EvalStatus = getEvalStatus();
   if (EvalStatus.Diag) {
     if (hasPriorDiagnostic()) {
       return OptionalDiagnostic();
     }
 
     unsigned CallStackNotes = getCallStackDepth() - 1;
-    unsigned Limit =
-        getASTContext().getDiagnostics().getConstexprBacktraceLimit();
+    unsigned Limit = Ctx.getDiagnostics().getConstexprBacktraceLimit();
     if (Limit)
       CallStackNotes = std::min(CallStackNotes, Limit + 1);
     if (checkingPotentialConstantExpression())
@@ -158,3 +156,53 @@ void State::addCallStack(unsigned Limit) {
           << Out.str() << CallRange;
   }
 }
+
+bool State::hasPriorDiagnostic() {
+  if (!EvalStatus.Diag->empty()) {
+    switch (EvalMode) {
+    case EvaluationMode::ConstantFold:
+    case EvaluationMode::IgnoreSideEffects:
+      if (!HasFoldFailureDiagnostic)
+        break;
+      // We've already failed to fold something. Keep that diagnostic.
+      [[fallthrough]];
+    case EvaluationMode::ConstantExpression:
+    case EvaluationMode::ConstantExpressionUnevaluated:
+      setActiveDiagnostic(false);
+      return true;
+    }
+  }
+  return false;
+}
+
+bool State::keepEvaluatingAfterFailure() const {
+  uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit;
+  if (Limit != 0 && !stepsLeft())
+    return false;
+
+  switch (EvalMode) {
+  case EvaluationMode::ConstantExpression:
+  case EvaluationMode::ConstantExpressionUnevaluated:
+  case EvaluationMode::ConstantFold:
+  case EvaluationMode::IgnoreSideEffects:
+    return checkingPotentialConstantExpression() ||
+           checkingForUndefinedBehavior();
+  }
+  llvm_unreachable("Missed EvalMode case");
+}
+
+bool State::keepEvaluatingAfterSideEffect() const {
+  switch (EvalMode) {
+  case EvaluationMode::IgnoreSideEffects:
+    return true;
+
+  case EvaluationMode::ConstantExpression:
+  case EvaluationMode::ConstantExpressionUnevaluated:
+  case EvaluationMode::ConstantFold:
+    // By default, assume any side effect might be valid in some other
+    // evaluation of this expression from a different context.
+    return checkingPotentialConstantExpression() ||
+           checkingForUndefinedBehavior();
+  }
+  llvm_unreachable("Missed EvalMode case");
+}
diff --git a/clang/lib/AST/ByteCode/State.h b/clang/lib/AST/ByteCode/State.h
index 2d30ff4596cc7..c0d32fba7fd9b 100644
--- a/clang/lib/AST/ByteCode/State.h
+++ b/clang/lib/AST/ByteCode/State.h
@@ -13,6 +13,7 @@
 #ifndef LLVM_CLANG_AST_INTERP_STATE_H
 #define LLVM_CLANG_AST_INTERP_STATE_H
 
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDiagnostic.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/OptionalDiagnostic.h"
@@ -79,21 +80,40 @@ class SourceInfo;
 /// Interface for the VM to interact with the AST walker's context.
 class State {
 public:
+  State(ASTContext &ASTCtx, Expr::EvalStatus &EvalStatus)
+      : Ctx(ASTCtx), EvalStatus(EvalStatus) {}
   virtual ~State();
 
-  virtual bool noteUndefinedBehavior() = 0;
-  virtual bool keepEvaluatingAfterFailure() const = 0;
-  virtual bool keepEvaluatingAfterSideEffect() const = 0;
-  virtual Frame *getCurrentFrame() = 0;
+  virtual const Frame *getCurrentFrame() = 0;
   virtual const Frame *getBottomFrame() const = 0;
-  virtual bool hasActiveDiagnostic() = 0;
-  virtual void setActiveDiagnostic(bool Flag) = 0;
-  virtual void setFoldFailureDiagnostic(bool Flag) = 0;
-  virtual Expr::EvalStatus &getEvalStatus() const = 0;
-  virtual ASTContext &getASTContext() const = 0;
-  virtual bool hasPriorDiagnostic() = 0;
   virtual unsigned getCallStackDepth() = 0;
-  virtual bool noteSideEffect() = 0;
+  virtual bool stepsLeft() const = 0;
+
+  Expr::EvalStatus &getEvalStatus() const { return EvalStatus; }
+  ASTContext &getASTContext() const { return Ctx; }
+  const LangOptions &getLangOpts() const { return Ctx.getLangOpts(); }
+
+  /// Note that we have had a side-effect, and determine whether we should
+  /// keep evaluating.
+  bool noteSideEffect() const {
+    EvalStatus.HasSideEffects = true;
+    return keepEvaluatingAfterSideEffect();
+  }
+
+  /// Should we continue evaluation as much as possible after encountering a
+  /// construct which can't be reduced to a value?
+  bool keepEvaluatingAfterFailure() const;
+  /// Should we continue evaluation after encountering a side-effect that we
+  /// couldn't model?
+  bool keepEvaluatingAfterSideEffect() const;
+
+  /// Note that we hit something that was technically undefined behavior, but
+  /// that we can evaluate past it (such as signed overflow or floating-point
+  /// division by zero.)
+  bool noteUndefinedBehavior() const {
+    EvalStatus.HasUndefinedBehavior = true;
+    return keepEvaluatingAfterUndefinedBehavior();
+  }
 
   /// Are we checking whether the expression is a potential constant
   /// expression?
@@ -105,8 +125,6 @@ class State {
     return CheckingForUndefinedBehavior;
   }
 
-public:
-  State() = default;
   /// Diagnose that the evaluation could not be folded (FF => FoldFailure)
   OptionalDiagnostic
   FFDiag(SourceLocation Loc,
@@ -119,7 +137,7 @@ class State {
          unsigned ExtraNotes = 0);
 
   OptionalDiagnostic
-  FFDiag(const SourceInfo &SI,
+  FFDiag(SourceInfo SI,
          diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
          unsigned ExtraNotes = 0);
 
@@ -139,7 +157,7 @@ class State {
           unsigned ExtraNotes = 0);
 
   OptionalDiagnostic
-  CCEDiag(const SourceInfo &SI,
+  CCEDiag(SourceInfo SI,
           diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
           unsigned ExtraNotes = 0);
 
@@ -170,14 +188,50 @@ class State {
   bool CheckingForUndefinedBehavior = false;
 
   EvaluationMode EvalMode;
+  ASTContext &Ctx;
+  Expr::EvalStatus &EvalStatus;
 
 private:
+  /// HasActiveDiagnostic - Was the previous diagnostic stored? If so, further
+  /// notes attached to it will also be stored, otherwise they will not be.
+  bool HasActiveDiagnostic = false;
+
+  /// Have we emitted a diagnostic explaining why we couldn't constant
+  /// fold (not just why it's not strictly a constant expression)?
+  bool HasFoldFailureDiagnostic = false;
+
   void addCallStack(unsigned Limit);
 
   PartialDiagnostic &addDiag(SourceLocation Loc, diag::kind DiagId);
 
   OptionalDiagnostic diag(SourceLocation Loc, diag::kind DiagId,
                           unsigned ExtraNotes, bool IsCCEDiag);
+
+  /// Should we continue evaluation after encountering undefined behavior?
+  bool keepEvaluatingAfterUndefinedBehavior() const {
+    switch (EvalMode) {
+    case EvaluationMode::IgnoreSideEffects:
+    case EvaluationMode::ConstantFold:
+      return true;
+
+    case EvaluationMode::ConstantExpression:
+    case EvaluationMode::ConstantExpressionUnevaluated:
+      return checkingForUndefinedBehavior();
+    }
+    llvm_unreachable("Missed EvalMode case");
+  }
+
+  // If we have a prior diagnostic, it will be noting that the expression
+  // isn't a constant expression. This diagnostic is more important,
+  // unless we require this evaluation to produce a constant expression.
+  //
+  // FIXME: We might want to show both diagnostics to the user in
+  // EvaluationMode::ConstantFold mode.
+  bool hasPriorDiagnostic();
+
+  void setFoldFailureDiagnostic(bool Flag) { HasFoldFailureDiagnostic = Flag; 
};
+  void setActiveDiagnostic(bool Flag) { HasActiveDiagnostic = Flag; };
+  bool hasActiveDiagnostic() const { return HasActiveDiagnostic; }
 };
 
 } // namespace interp
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 58748fa5ba49b..91d0c655abfc6 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -794,13 +794,8 @@ namespace {
   /// rules.  For example, the RHS of (0 && foo()) is not evaluated.  We can
   /// evaluate the expression regardless of what the RHS is, but C only allows
   /// certain things in certain situations.
-  class EvalInfo : public interp::State {
+  class EvalInfo final : public interp::State {
   public:
-    ASTContext &Ctx;
-
-    /// EvalStatus - Contains information about the evaluation.
-    Expr::EvalStatus &EvalStatus;
-
     /// CurrentCall - The top of the constexpr call stack.
     CallStackFrame *CurrentCall;
 
@@ -919,16 +914,8 @@ namespace {
     /// initialization.
     uint64_t ArrayInitIndex = -1;
 
-    /// HasActiveDiagnostic - Was the previous diagnostic stored? If so, 
further
-    /// notes attached to it will also be stored, otherwise they will not be.
-    bool HasActiveDiagnostic;
-
-    /// Have we emitted a diagnostic explaining why we couldn't constant
-    /// fold (not just why it's not strictly a constant expression)?
-    bool HasFoldFailureDiagnostic;
-
     EvalInfo(const ASTContext &C, Expr::EvalStatus &S, EvaluationMode Mode)
-        : Ctx(const_cast<ASTContext &>(C)), EvalStatus(S), 
CurrentCall(nullptr),
+        : State(const_cast<ASTContext &>(C), S), CurrentCall(nullptr),
           CallStackDepth(0), NextCallIndex(1),
           StepsLeft(C.getLangOpts().ConstexprStepLimit),
           EnableNewConstInterp(C.getLangOpts().EnableNewConstInterp),
@@ -936,8 +923,7 @@ namespace {
                       /*This=*/nullptr,
                       /*CallExpr=*/nullptr, CallRef()),
           EvaluatingDecl((const ValueDecl *)nullptr),
-          EvaluatingDeclValue(nullptr), HasActiveDiagnostic(false),
-          HasFoldFailureDiagnostic(false) {
+          EvaluatingDeclValue(nullptr) {
       EvalMode = Mode;
     }
 
@@ -945,9 +931,6 @@ namespace {
       discardCleanups();
     }
 
-    ASTContext &getASTContext() const override { return Ctx; }
-    const LangOptions &getLangOpts() const { return Ctx.getLangOpts(); }
-
     void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value,
                            EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
       EvaluatingDecl = Base;
@@ -990,7 +973,7 @@ namespace {
       // We use the number of constexpr steps as a proxy for the maximum size
       // of arrays to avoid exhausting the system resources, as initialization
       // of each element is likely to take some number of steps anyway.
-      uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit;
+      uint64_t Limit = getLangOpts().ConstexprStepLimit;
       if (Limit != 0 && ElemCount > Limit) {
         if (Diag)
           FFDiag(Loc, diag::note_constexpr_new_exceeds_limits)
@@ -1017,7 +1000,7 @@ namespace {
     }
 
     bool nextStep(const Stmt *S) {
-      if (Ctx.getLangOpts().ConstexprStepLimit == 0)
+      if (getLangOpts().ConstexprStepLimit == 0)
         return true;
 
       if (!StepsLeft) {
@@ -1101,110 +1084,13 @@ namespace {
     }
 
   private:
-    interp::Frame *getCurrentFrame() override { return CurrentCall; }
+    const interp::Frame *getCurrentFrame() override { return CurrentCall; }
     const interp::Frame *getBottomFrame() const override { return 
&BottomFrame; }
 
-    bool hasActiveDiagnostic() override { return HasActiveDiagnostic; }
-    void setActiveDiagnostic(bool Flag) override { HasActiveDiagnostic = Flag; 
}
-
-    void setFoldFailureDiagnostic(bool Flag) override {
-      HasFoldFailureDiagnostic = Flag;
-    }
-
-    Expr::EvalStatus &getEvalStatus() const override { return EvalStatus; }
-
-    // If we have a prior diagnostic, it will be noting that the expression
-    // isn't a constant expression. This diagnostic is more important,
-    // unless we require this evaluation to produce a constant expression.
-    //
-    // FIXME: We might want to show both diagnostics to the user in
-    // EvaluationMode::ConstantFold mode.
-    bool hasPriorDiagnostic() override {
-      if (!EvalStatus.Diag->empty()) {
-        switch (EvalMode) {
-        case EvaluationMode::ConstantFold:
-        case EvaluationMode::IgnoreSideEffects:
-          if (!HasFoldFailureDiagnostic)
-            break;
-          // We've already failed to fold something. Keep that diagnostic.
-          [[fallthrough]];
-        case EvaluationMode::ConstantExpression:
-        case EvaluationMode::ConstantExpressionUnevaluated:
-          setActiveDiagnostic(false);
-          return true;
-        }
-      }
-      return false;
-    }
-
     unsigned getCallStackDepth() override { return CallStackDepth; }
+    bool stepsLeft() const override { return StepsLeft > 0; }
 
   public:
-    /// Should we continue evaluation after encountering a side-effect that we
-    /// couldn't model?
-    bool keepEvaluatingAfterSideEffect() const override {
-      switch (EvalMode) {
-      case EvaluationMode::IgnoreSideEffects:
-        return true;
-
-      case EvaluationMode::ConstantExpression:
-      case EvaluationMode::ConstantExpressionUnevaluated:
-      case EvaluationMode::ConstantFold:
-        // By default, assume any side effect might be valid in some other
-        // evaluation of this expression from a different context.
-        return checkingPotentialConstantExpression() ||
-               checkingForUndefinedBehavior();
-      }
-      llvm_unreachable("Missed EvalMode case");
-    }
-
-    /// Note that we have had a side-effect, and determine whether we should
-    /// keep evaluating.
-    bool noteSideEffect() override {
-      EvalStatus.HasSideEffects = true;
-      return keepEvaluatingAfterSideEffect();
-    }
-
-    /// Should we continue evaluation after encountering undefined behavior?
-    bool keepEvaluatingAfterUndefinedBehavior() {
-      switch (EvalMode) {
-      case EvaluationMode::IgnoreSideEffects:
-      case EvaluationMode::ConstantFold:
-        return true;
-
-      case EvaluationMode::ConstantExpression:
-      case EvaluationMode::ConstantExpressionUnevaluated:
-        return checkingForUndefinedBehavior();
-      }
-      llvm_unreachable("Missed EvalMode case");
-    }
-
-    /// Note that we hit something that was technically undefined behavior, but
-    /// that we can evaluate past it (such as signed overflow or floating-point
-    /// division by zero.)
-    bool noteUndefinedBehavior() override {
-      EvalStatus.HasUndefinedBehavior = true;
-      return keepEvaluatingAfterUndefinedBehavior();
-    }
-
-    /// Should we continue evaluation as much as possible after encountering a
-    /// construct which can't be reduced to a value?
-    bool keepEvaluatingAfterFailure() const override {
-      uint64_t Limit = Ctx.getLangOpts().ConstexprStepLimit;
-      if (Limit != 0 && !StepsLeft)
-        return false;
-
-      switch (EvalMode) {
-      case EvaluationMode::ConstantExpression:
-      case EvaluationMode::ConstantExpressionUnevaluated:
-      case EvaluationMode::ConstantFold:
-      case EvaluationMode::IgnoreSideEffects:
-        return checkingPotentialConstantExpression() ||
-               checkingForUndefinedBehavior();
-      }
-      llvm_unreachable("Missed EvalMode case");
-    }
-
     /// Notes that we failed to evaluate an expression that other expressions
     /// directly depend on, and determine if we should keep evaluating. This
     /// should only be called if we actually intend to keep evaluating.
@@ -2412,9 +2298,8 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, 
SourceLocation Loc,
 
       // In CUDA/HIP device compilation, only device side variables have
       // constant addresses.
-      if (Info.getASTContext().getLangOpts().CUDA &&
-          Info.getASTContext().getLangOpts().CUDAIsDevice &&
-          Info.getASTContext().CUDAConstantEvalCtx.NoWrongSidedVars) {
+      if (Info.getLangOpts().CUDA && Info.getLangOpts().CUDAIsDevice &&
+          Info.Ctx.CUDAConstantEvalCtx.NoWrongSidedVars) {
         if ((!Var->hasAttr<CUDADeviceAttr>() &&
              !Var->hasAttr<CUDAConstantAttr>() &&
              !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
@@ -2767,7 +2652,7 @@ static bool HandleFloatToIntCast(EvalInfo &Info, const 
Expr *E,
 /// So return "tonearest" mode instead of "dynamic".
 static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E) 
{
   llvm::RoundingMode RM =
-      E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).getRoundingMode();
+      E->getFPFeaturesInEffect(Info.getLangOpts()).getRoundingMode();
   if (RM == llvm::RoundingMode::Dynamic)
     RM = llvm::RoundingMode::NearestTiesToEven;
   return RM;
@@ -2781,7 +2666,7 @@ static bool checkFloatingPointResult(EvalInfo &Info, 
const Expr *E,
   if (Info.InConstantContext)
     return true;
 
-  FPOptions FPO = E->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
+  FPOptions FPO = E->getFPFeaturesInEffect(Info.getLangOpts());
   if ((St & APFloat::opInexact) &&
       FPO.getRoundingMode() == llvm::RoundingMode::Dynamic) {
     // Inexact result means that it depends on rounding mode. If the requested
@@ -6326,7 +6211,7 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, 
EvalInfo &Info,
         *Info.CurrentCall, hasSpecificAttr<MSConstexprAttr>(AS->getAttrs()) &&
                                isa<ReturnStmt>(SS));
 
-    auto LO = Info.getASTContext().getLangOpts();
+    auto LO = Info.Ctx.getLangOpts();
     if (LO.CXXAssumptions && !LO.MSVCCompat) {
       for (auto *Attr : AS->getAttrs()) {
         auto *AA = dyn_cast<CXXAssumeAttr>(Attr);
@@ -6337,7 +6222,7 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, 
EvalInfo &Info,
         if (Assumption->isValueDependent())
           return ESR_Failed;
 
-        if (Assumption->HasSideEffects(Info.getASTContext()))
+        if (Assumption->HasSideEffects(Info.Ctx))
           continue;
 
         bool Value;
@@ -9325,8 +9210,8 @@ class LValueExprEvaluator
   bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
   bool VisitMemberExpr(const MemberExpr *E);
   bool VisitStringLiteral(const StringLiteral *E) {
-    return Success(APValue::LValueBase(
-        E, 0, Info.getASTContext().getNextStringLiteralVersion()));
+    return Success(
+        APValue::LValueBase(E, 0, Info.Ctx.getNextStringLiteralVersion()));
   }
   bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E) { return Success(E); }
   bool VisitCXXTypeidExpr(const CXXTypeidExpr *E);

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to