https://github.com/NagyDonat created 
https://github.com/llvm/llvm-project/pull/181431

The class `StmtNodeBuilder` was practically equivalent to its base class 
`NodeBuilder` -- its data members and constructors were identical and the only 
distinguishing feature was that it supported two additional methods that were 
not present in `NodeBuilder`.

This commit moves those two methods to `NodeBuilder` (there is no reason why 
they cannot be defined there) and replaces all references to `StmtNodeBuilder` 
with plain `NodeBuilder`.

Note that previously `StmtNodeBuilder` had a distinguishing feature where its 
destructor could pass nodes to an "enclosing node builder" but this became dead 
code somewhen in the past, so my previous commit 
320d0b5467b9586a188e06dd2620126f5cb99318 removed it.

From fdc6c6022a0944d7ceeb3a36eef23fb99d147e2b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Fri, 13 Feb 2026 23:17:36 +0100
Subject: [PATCH] [NFC][analyzer] Remove StmtNodeBuilder

The class `StmtNodeBuilder` was practically equivalent to its base class
`NodeBuilder` -- its data members and constructors were identical and
the only distinguishing feature was that it supported two additional
methods that were not present in `NodeBuilder`.

This commit moves those two methods to `NodeBuilder` (there is no reason
why they cannot be defined there) and replaces all references to
`StmtNodeBuilder` with plain `NodeBuilder`.

Note that previously `StmtNodeBuilder` had a distinguishing feature
where its destructor could pass nodes to an "enclosing node builder" but
this became dead code somewhen in the past, so my previous commit
320d0b5467b9586a188e06dd2620126f5cb99318 removed it.
---
 .../Core/PathSensitive/CoreEngine.h           | 51 ++++++-------------
 .../Core/PathSensitive/ExprEngine.h           |  5 +-
 clang/lib/StaticAnalyzer/Core/ExprEngine.cpp  | 42 +++++++--------
 clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 35 ++++++-------
 .../lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 32 ++++++------
 .../Core/ExprEngineCallAndReturn.cpp          |  2 +-
 .../StaticAnalyzer/Core/ExprEngineObjC.cpp    | 22 ++++----
 clang/test/Analysis/misc-ps-eager-assume.m    |  3 ++
 8 files changed, 89 insertions(+), 103 deletions(-)

diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h 
b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index f8d444251ec9f..5ff9a1025a5e3 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -291,39 +291,6 @@ class NodeBuilder {
     return generateNodeImpl(PP, State, Pred, true);
   }
 
-  const ExplodedNodeSet &getResults() { return Frontier; }
-
-  const NodeBuilderContext &getContext() { return C; }
-  bool hasGeneratedNodes() { return HasGeneratedNodes; }
-
-  void takeNodes(const ExplodedNodeSet &S) {
-    for (const auto I : S)
-      Frontier.erase(I);
-  }
-
-  void takeNodes(ExplodedNode *N) { Frontier.erase(N); }
-  void addNodes(const ExplodedNodeSet &S) { Frontier.insert(S); }
-  void addNodes(ExplodedNode *N) { Frontier.Add(N); }
-};
-
-/// \class StmtNodeBuilder
-/// This builder class is useful for generating nodes that resulted from
-/// visiting a statement. The main difference from its parent NodeBuilder is
-/// that it creates a statement specific ProgramPoint.
-/// FIXME: This class is not meaningfully different from plain NodeBuilder.
-class StmtNodeBuilder : public NodeBuilder {
-public:
-  StmtNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
-                  const NodeBuilderContext &Ctx)
-      : NodeBuilder(SrcNode, DstSet, Ctx) {}
-
-  StmtNodeBuilder(ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
-                  const NodeBuilderContext &Ctx)
-      : NodeBuilder(SrcSet, DstSet, Ctx) {}
-
-  using NodeBuilder::generateNode;
-  using NodeBuilder::generateSink;
-
   ExplodedNode *generateNode(const Stmt *S,
                              ExplodedNode *Pred,
                              ProgramStateRef St,
@@ -331,7 +298,7 @@ class StmtNodeBuilder : public NodeBuilder {
                              ProgramPoint::Kind K = 
ProgramPoint::PostStmtKind){
     const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
                                   Pred->getLocationContext(), tag);
-    return NodeBuilder::generateNode(L, St, Pred);
+    return generateNode(L, St, Pred);
   }
 
   ExplodedNode *generateSink(const Stmt *S,
@@ -341,8 +308,22 @@ class StmtNodeBuilder : public NodeBuilder {
                              ProgramPoint::Kind K = 
ProgramPoint::PostStmtKind){
     const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
                                   Pred->getLocationContext(), tag);
-    return NodeBuilder::generateSink(L, St, Pred);
+    return generateSink(L, St, Pred);
   }
+
+  const ExplodedNodeSet &getResults() { return Frontier; }
+
+  const NodeBuilderContext &getContext() { return C; }
+  bool hasGeneratedNodes() { return HasGeneratedNodes; }
+
+  void takeNodes(const ExplodedNodeSet &S) {
+    for (const auto I : S)
+      Frontier.erase(I);
+  }
+
+  void takeNodes(ExplodedNode *N) { Frontier.erase(N); }
+  void addNodes(const ExplodedNodeSet &S) { Frontier.insert(S); }
+  void addNodes(ExplodedNode *N) { Frontier.Add(N); }
 };
 
 /// BranchNodeBuilder is responsible for constructing the nodes
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h 
b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 20f62f93f9095..40bc96c954267 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -616,11 +616,10 @@ class ExprEngine {
   ProgramStateRef handleLValueBitCast(ProgramStateRef state, const Expr *Ex,
                                       const LocationContext *LCtx, QualType T,
                                       QualType ExTy, const CastExpr *CastE,
-                                      StmtNodeBuilder &Bldr,
-                                      ExplodedNode *Pred);
+                                      NodeBuilder &Bldr, ExplodedNode *Pred);
 
   void handleUOExtension(ExplodedNode *N, const UnaryOperator *U,
-                         StmtNodeBuilder &Bldr);
+                         NodeBuilder &Bldr);
 
 public:
   SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op,
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 47312a53f61ff..e0bc083f6b978 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1088,7 +1088,7 @@ void ExprEngine::removeDead(ExplodedNode *Pred, 
ExplodedNodeSet &Out,
   // For each node in CheckedSet, generate CleanedNodes that have the
   // environment, the store, and the constraints cleaned up but have the
   // user-supplied states as the predecessors.
-  StmtNodeBuilder Bldr(CheckedSet, Out, *currBldrCtx);
+  NodeBuilder Bldr(CheckedSet, Out, *currBldrCtx);
   for (const auto I : CheckedSet) {
     ProgramStateRef CheckerState = I->getState();
 
@@ -1599,8 +1599,8 @@ void ExprEngine::ProcessTemporaryDtor(const 
CFGTemporaryDtor D,
   }
 
   ExplodedNodeSet CleanDtorState;
-  StmtNodeBuilder StmtBldr(Pred, CleanDtorState, *currBldrCtx);
-  StmtBldr.generateNode(D.getBindTemporaryExpr(), Pred, State);
+  NodeBuilder Builder(Pred, CleanDtorState, *currBldrCtx);
+  Builder.generateNode(D.getBindTemporaryExpr(), Pred, State);
 
   QualType T = D.getBindTemporaryExpr()->getSubExpr()->getType();
   // FIXME: Currently CleanDtorState can be empty here due to temporaries being
@@ -1672,7 +1672,7 @@ void ExprEngine::VisitCXXBindTemporaryExpr(const 
CXXBindTemporaryExpr *BTE,
     Dst = PreVisit;
     return;
   }
-  StmtNodeBuilder StmtBldr(PreVisit, Dst, *currBldrCtx);
+  NodeBuilder Builder(PreVisit, Dst, *currBldrCtx);
   for (ExplodedNode *Node : PreVisit) {
     ProgramStateRef State = Node->getState();
     const LocationContext *LC = Node->getLocationContext();
@@ -1683,7 +1683,7 @@ void ExprEngine::VisitCXXBindTemporaryExpr(const 
CXXBindTemporaryExpr *BTE,
       // temporary destructor nodes.
       State = addObjectUnderConstruction(State, BTE, LC, UnknownVal());
     }
-    StmtBldr.generateNode(BTE, Node, State);
+    Builder.generateNode(BTE, Node, State);
   }
 }
 
@@ -1719,7 +1719,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
   PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
                                 S->getBeginLoc(), "Error evaluating 
statement");
   ExplodedNodeSet Dst;
-  StmtNodeBuilder Bldr(Pred, DstTop, *currBldrCtx);
+  NodeBuilder Bldr(Pred, DstTop, *currBldrCtx);
 
   assert(!isa<Expr>(S) || S == cast<Expr>(S)->IgnoreParens());
 
@@ -2002,7 +2002,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
       getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
 
       ExplodedNodeSet Tmp;
-      StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx);
+      NodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx);
 
       const Expr *ArgE;
       if (const auto *DefE = dyn_cast<CXXDefaultArgExpr>(S))
@@ -2049,7 +2049,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
       getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
 
       ExplodedNodeSet Tmp;
-      StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx);
+      NodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx);
 
       const auto *Ex = cast<Expr>(S);
       QualType resultType = Ex->getType();
@@ -3179,7 +3179,7 @@ void ExprEngine::processSwitch(NodeBuilderContext &BC, 
const SwitchStmt *Switch,
 void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
                                         ExplodedNode *Pred,
                                         ExplodedNodeSet &Dst) {
-  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
+  NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
 
   ProgramStateRef state = Pred->getState();
   const LocationContext *LCtx = Pred->getLocationContext();
@@ -3344,7 +3344,7 @@ void ExprEngine::VisitArrayInitLoopExpr(const 
ArrayInitLoopExpr *Ex,
   getCheckerManager().runCheckersForPreStmt(CheckerPreStmt, Pred, Ex, *this);
 
   ExplodedNodeSet EvalSet;
-  StmtNodeBuilder Bldr(CheckerPreStmt, EvalSet, *currBldrCtx);
+  NodeBuilder Bldr(CheckerPreStmt, EvalSet, *currBldrCtx);
 
   const Expr *Arr = Ex->getCommonExpr()->getSourceExpr();
 
@@ -3445,7 +3445,7 @@ void ExprEngine::VisitArraySubscriptExpr(const 
ArraySubscriptExpr *A,
   getCheckerManager().runCheckersForPreStmt(CheckerPreStmt, Pred, A, *this);
 
   ExplodedNodeSet EvalSet;
-  StmtNodeBuilder Bldr(CheckerPreStmt, EvalSet, *currBldrCtx);
+  NodeBuilder Bldr(CheckerPreStmt, EvalSet, *currBldrCtx);
 
   bool IsVectorType = A->getBase()->getType()->isVectorType();
 
@@ -3501,7 +3501,7 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, 
ExplodedNode *Pred,
     for (const auto I : CheckedSet)
       VisitCommonDeclRefExpr(M, Member, I, EvalSet);
   } else {
-    StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
+    NodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
     ExplodedNodeSet Tmp;
 
     for (const auto I : CheckedSet) {
@@ -3583,7 +3583,7 @@ void ExprEngine::VisitAtomicExpr(const AtomicExpr *AE, 
ExplodedNode *Pred,
   // FIXME: Ideally we should model the behavior of the atomics precisely here.
 
   ExplodedNodeSet AfterInvalidateSet;
-  StmtNodeBuilder Bldr(AfterPreSet, AfterInvalidateSet, *currBldrCtx);
+  NodeBuilder Bldr(AfterPreSet, AfterInvalidateSet, *currBldrCtx);
 
   for (const auto I : AfterPreSet) {
     ProgramStateRef State = I->getState();
@@ -3725,7 +3725,7 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const 
Stmt *StoreE,
   getCheckerManager().runCheckersForBind(CheckedSet, Pred, location, Val,
                                          StoreE, AtDeclInit, *this, *PP);
 
-  StmtNodeBuilder Bldr(CheckedSet, Dst, *currBldrCtx);
+  NodeBuilder Bldr(CheckedSet, Dst, *currBldrCtx);
 
   // If the location is not a 'Loc', it will already be handled by
   // the checkers.  There is nothing left to do.
@@ -3808,7 +3808,7 @@ void ExprEngine::evalLoad(ExplodedNodeSet &Dst,
   if (Tmp.empty())
     return;
 
-  StmtNodeBuilder Bldr(Tmp, Dst, *currBldrCtx);
+  NodeBuilder Bldr(Tmp, Dst, *currBldrCtx);
   if (location.isUndef())
     return;
 
@@ -3836,7 +3836,7 @@ void ExprEngine::evalLocation(ExplodedNodeSet &Dst,
                               ProgramStateRef state,
                               SVal location,
                               bool isLoad) {
-  StmtNodeBuilder BldrTop(Pred, Dst, *currBldrCtx);
+  NodeBuilder BldrTop(Pred, Dst, *currBldrCtx);
   // Early checks for performance reason.
   if (location.isUnknown()) {
     return;
@@ -3844,7 +3844,7 @@ void ExprEngine::evalLocation(ExplodedNodeSet &Dst,
 
   ExplodedNodeSet Src;
   BldrTop.takeNodes(Pred);
-  StmtNodeBuilder Bldr(Pred, Src, *currBldrCtx);
+  NodeBuilder Bldr(Pred, Src, *currBldrCtx);
   if (Pred->getState() != state) {
     // Associate this new state with an ExplodedNode.
     // FIXME: If I pass null tag, the graph is incorrect, e.g for
@@ -3881,7 +3881,7 @@ 
REGISTER_TRAIT_WITH_PROGRAMSTATE(LastEagerlyAssumeExprIfSuccessful,
 void ExprEngine::evalEagerlyAssumeBifurcation(ExplodedNodeSet &Dst,
                                               ExplodedNodeSet &Src,
                                               const Expr *Ex) {
-  StmtNodeBuilder Bldr(Src, Dst, *currBldrCtx);
+  NodeBuilder Bldr(Src, Dst, *currBldrCtx);
 
   for (ExplodedNode *Pred : Src) {
     // Test if the previous node was as the same expression.  This can happen
@@ -3930,7 +3930,7 @@ bool 
ExprEngine::didEagerlyAssumeBifurcateAt(ProgramStateRef State,
 
 void ExprEngine::VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
                                  ExplodedNodeSet &Dst) {
-  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
+  NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
   // We have processed both the inputs and the outputs.  All of the outputs
   // should evaluate to Locs.  Nuke all of their values.
 
@@ -3967,7 +3967,7 @@ void ExprEngine::VisitGCCAsmStmt(const GCCAsmStmt *A, 
ExplodedNode *Pred,
 
 void ExprEngine::VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred,
                                 ExplodedNodeSet &Dst) {
-  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
+  NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
   Bldr.generateNode(A, Pred, Pred->getState());
 }
 
@@ -4134,7 +4134,7 @@ void ExprEngine::ConstructInitList(const Expr *E, 
ArrayRef<Expr *> Args,
 
   const LocationContext *LC = Pred->getLocationContext();
 
-  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
+  NodeBuilder B(Pred, Dst, *currBldrCtx);
   ProgramStateRef S = Pred->getState();
   QualType T = E->getType().getCanonicalType();
 
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index db27c06cd18a3..b7fac30500d26 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -78,7 +78,7 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
     }
 
     if (!B->isAssignmentOp()) {
-      StmtNodeBuilder Bldr(*it, Tmp2, *currBldrCtx);
+      NodeBuilder Bldr(*it, Tmp2, *currBldrCtx);
 
       if (B->isAdditiveOp()) {
         // TODO: This can be removed after we enable history tracking with
@@ -246,7 +246,7 @@ void ExprEngine::VisitBlockExpr(const BlockExpr *BE, 
ExplodedNode *Pred,
   }
 
   ExplodedNodeSet Tmp;
-  StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
+  NodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
   Bldr.generateNode(BE, Pred,
                     State->BindExpr(BE, Pred->getLocationContext(), V),
                     nullptr, ProgramPoint::PostLValueKind);
@@ -255,10 +255,11 @@ void ExprEngine::VisitBlockExpr(const BlockExpr *BE, 
ExplodedNode *Pred,
   getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this);
 }
 
-ProgramStateRef ExprEngine::handleLValueBitCast(
-    ProgramStateRef state, const Expr* Ex, const LocationContext* LCtx,
-    QualType T, QualType ExTy, const CastExpr* CastE, StmtNodeBuilder& Bldr,
-    ExplodedNode* Pred) {
+ProgramStateRef
+ExprEngine::handleLValueBitCast(ProgramStateRef state, const Expr *Ex,
+                                const LocationContext *LCtx, QualType T,
+                                QualType ExTy, const CastExpr *CastE,
+                                NodeBuilder &Bldr, ExplodedNode *Pred) {
   if (T->isLValueReferenceType()) {
     assert(!CastE->getType()->isLValueReferenceType());
     ExTy = getContext().getLValueReferenceType(ExTy);
@@ -310,7 +311,7 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const 
Expr *Ex,
     }
     // Simulate the operation that actually casts the original value to a new
     // value of the destination type :
-    StmtNodeBuilder Bldr(DstEvalLoc, Dst, *currBldrCtx);
+    NodeBuilder Bldr(DstEvalLoc, Dst, *currBldrCtx);
 
     for (ExplodedNode *Node : DstEvalLoc) {
       ProgramStateRef State = Node->getState();
@@ -338,7 +339,7 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const 
Expr *Ex,
   if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
     T = ExCast->getTypeAsWritten();
 
-  StmtNodeBuilder Bldr(DstPreStmt, Dst, *currBldrCtx);
+  NodeBuilder Bldr(DstPreStmt, Dst, *currBldrCtx);
   for (ExplodedNode *Pred : DstPreStmt) {
     ProgramStateRef state = Pred->getState();
     const LocationContext *LCtx = Pred->getLocationContext();
@@ -579,7 +580,7 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const 
Expr *Ex,
 void ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
                                           ExplodedNode *Pred,
                                           ExplodedNodeSet &Dst) {
-  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
+  NodeBuilder B(Pred, Dst, *currBldrCtx);
 
   ProgramStateRef State = Pred->getState();
   const LocationContext *LCtx = Pred->getLocationContext();
@@ -629,7 +630,7 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, 
ExplodedNode *Pred,
   getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
 
   ExplodedNodeSet dstEvaluated;
-  StmtNodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx);
+  NodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx);
   for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = 
dstPreVisit.end();
        I!=E; ++I) {
     ExplodedNode *N = *I;
@@ -698,7 +699,7 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, 
ExplodedNode *Pred,
   assert(B->getOpcode() == BO_LAnd ||
          B->getOpcode() == BO_LOr);
 
-  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
+  NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
   ProgramStateRef state = Pred->getState();
 
   if (B->getType()->isVectorType()) {
@@ -779,7 +780,7 @@ void ExprEngine::VisitGuardedExpr(const Expr *Ex,
                                   ExplodedNodeSet &Dst) {
   assert(L && R);
 
-  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
+  NodeBuilder B(Pred, Dst, *currBldrCtx);
   ProgramStateRef state = Pred->getState();
   const LocationContext *LCtx = Pred->getLocationContext();
   const CFGBlock *SrcBlock = nullptr;
@@ -839,7 +840,7 @@ void ExprEngine::VisitGuardedExpr(const Expr *Ex,
 void ExprEngine::
 VisitOffsetOfExpr(const OffsetOfExpr *OOE,
                   ExplodedNode *Pred, ExplodedNodeSet &Dst) {
-  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
+  NodeBuilder B(Pred, Dst, *currBldrCtx);
   Expr::EvalResult Result;
   if (OOE->EvaluateAsInt(Result, getContext())) {
     APSInt IV = Result.Val.getInt();
@@ -864,7 +865,7 @@ VisitUnaryExprOrTypeTraitExpr(const 
UnaryExprOrTypeTraitExpr *Ex,
   getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, Ex, *this);
 
   ExplodedNodeSet EvalSet;
-  StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
+  NodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
 
   QualType T = Ex->getTypeOfArgument();
 
@@ -899,7 +900,7 @@ VisitUnaryExprOrTypeTraitExpr(const 
UnaryExprOrTypeTraitExpr *Ex,
 }
 
 void ExprEngine::handleUOExtension(ExplodedNode *N, const UnaryOperator *U,
-                                   StmtNodeBuilder &Bldr) {
+                                   NodeBuilder &Bldr) {
   // FIXME: We can probably just have some magic in Environment::getSVal()
   // that propagates values, instead of creating a new node here.
   //
@@ -920,7 +921,7 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, 
ExplodedNode *Pred,
   getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, U, *this);
 
   ExplodedNodeSet EvalSet;
-  StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
+  NodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
 
   for (ExplodedNode *N : CheckedSet) {
     switch (U->getOpcode()) {
@@ -1065,7 +1066,7 @@ void ExprEngine::VisitIncrementDecrementOperator(const 
UnaryOperator* U,
   evalLoad(Tmp, U, Ex, Pred, state, loc);
 
   ExplodedNodeSet Dst2;
-  StmtNodeBuilder Bldr(Tmp, Dst2, *currBldrCtx);
+  NodeBuilder Bldr(Tmp, Dst2, *currBldrCtx);
   for (ExplodedNode *N : Tmp) {
     state = N->getState();
     assert(LCtx == N->getLocationContext());
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index 99751482dee40..43dad6fef7d65 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -33,7 +33,7 @@ using namespace ento;
 void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
                                           ExplodedNode *Pred,
                                           ExplodedNodeSet &Dst) {
-  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
+  NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
   const Expr *tempExpr = ME->getSubExpr()->IgnoreParens();
   ProgramStateRef state = Pred->getState();
   const LocationContext *LCtx = Pred->getLocationContext();
@@ -563,7 +563,7 @@ void ExprEngine::handleConstructor(const Expr *E,
         // it in fact constructs into the correct target. This constructor can
         // therefore be skipped.
         Target = *ElidedTarget;
-        StmtNodeBuilder Bldr(Pred, destNodes, *currBldrCtx);
+        NodeBuilder Bldr(Pred, destNodes, *currBldrCtx);
         State = finishObjectConstruction(State, CE, LCtx);
         if (auto L = Target.getAs<Loc>())
           State = State->BindExpr(CE, LCtx, State->getSVal(*L, CE->getType()));
@@ -604,7 +604,7 @@ void ExprEngine::handleConstructor(const Expr *E,
 
       // No element construction will happen in a 0 size array.
       if (isZeroSizeArray()) {
-        StmtNodeBuilder Bldr(Pred, destNodes, *currBldrCtx);
+        NodeBuilder Bldr(Pred, destNodes, *currBldrCtx);
         static SimpleProgramPointTag T{"ExprEngine",
                                        "Skipping 0 size array construction"};
         Bldr.generateNode(CE, Pred, State, &T);
@@ -688,7 +688,7 @@ void ExprEngine::handleConstructor(const Expr *E,
     static SimpleProgramPointTag T("ExprEngine",
                                    "Prepare for object construction");
     ExplodedNodeSet DstPrepare;
-    StmtNodeBuilder BldrPrepare(Pred, DstPrepare, *currBldrCtx);
+    NodeBuilder BldrPrepare(Pred, DstPrepare, *currBldrCtx);
     Pred =
         BldrPrepare.generateNode(E, Pred, State, &T, 
ProgramPoint::PreStmtKind);
     if (!Pred)
@@ -709,7 +709,7 @@ void ExprEngine::handleConstructor(const Expr *E,
   ExplodedNodeSet PreInitialized;
   if (CE) {
     // FIXME: Is it possible and/or useful to do this before PreStmt?
-    StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
+    NodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
     for (ExplodedNode *N : DstPreVisit) {
       ProgramStateRef State = N->getState();
       if (CE->requiresZeroInitialization()) {
@@ -748,7 +748,7 @@ void ExprEngine::handleConstructor(const Expr *E,
   if (CE && CE->getConstructor()->isTrivial() &&
       CE->getConstructor()->isCopyOrMoveConstructor() &&
       !CallOpts.IsArrayCtorOrDtor) {
-    StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
+    NodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
     // FIXME: Handle other kinds of trivial constructors as well.
     for (ExplodedNode *N : DstPreCall)
       performTrivialCopy(Bldr, N, *Call);
@@ -767,7 +767,7 @@ void ExprEngine::handleConstructor(const Expr *E,
   // later (for life-time extended temporaries) -- but avoids infeasible
   // paths when no-return temporary destructors are used for assertions.
   ExplodedNodeSet DstEvaluatedPostProcessed;
-  StmtNodeBuilder Bldr(DstEvaluated, DstEvaluatedPostProcessed, *currBldrCtx);
+  NodeBuilder Bldr(DstEvaluated, DstEvaluatedPostProcessed, *currBldrCtx);
   const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext();
   if (!ADC->getCFGBuildOptions().AddTemporaryDtors) {
     if (llvm::isa_and_nonnull<CXXTempObjectRegion,
@@ -881,7 +881,7 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType,
                                             *Call, *this);
 
   ExplodedNodeSet DstInvalidated;
-  StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
+  NodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
   for (ExplodedNode *N : DstPreCall)
     defaultEvalCall(Bldr, N, *Call, CallOpts);
 
@@ -906,7 +906,7 @@ void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr 
*CNE,
                                             *Call, *this);
 
   ExplodedNodeSet DstPostCall;
-  StmtNodeBuilder CallBldr(DstPreCall, DstPostCall, *currBldrCtx);
+  NodeBuilder CallBldr(DstPreCall, DstPostCall, *currBldrCtx);
   for (ExplodedNode *I : DstPreCall) {
     // Operator new calls (CXXNewExpr) are intentionally not eval-called,
     // because it does not make sense to eval-call user-provided functions.
@@ -923,7 +923,7 @@ void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr 
*CNE,
   // Store return value of operator new() for future use, until the actual
   // CXXNewExpr gets processed.
   ExplodedNodeSet DstPostValue;
-  StmtNodeBuilder ValueBldr(DstPostCall, DstPostValue, *currBldrCtx);
+  NodeBuilder ValueBldr(DstPostCall, DstPostValue, *currBldrCtx);
   for (ExplodedNode *I : DstPostCall) {
     // FIXME: Because CNE serves as the "call site" for the allocator (due to
     // lack of a better expression in the AST), the conjured return value 
symbol
@@ -1029,7 +1029,7 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, 
ExplodedNode *Pred,
           State = State->assume(*dSymVal, true);
   }
 
-  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
+  NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
 
   SVal Result = symVal;
 
@@ -1114,7 +1114,7 @@ void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr 
*CDE,
   ExplodedNodeSet DstPostCall;
 
   if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
-    StmtNodeBuilder Bldr(DstPreCall, DstPostCall, *currBldrCtx);
+    NodeBuilder Bldr(DstPreCall, DstPostCall, *currBldrCtx);
     for (ExplodedNode *I : DstPreCall) {
       // Intentionally either inline or conservative eval-call the operator
       // delete, but avoid triggering an eval-call event for checkers.
@@ -1142,13 +1142,13 @@ void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt 
*CS, ExplodedNode *Pred,
   ProgramStateRef state = Pred->getState();
   state = state->bindLoc(state->getLValue(VD, LCtx), V, LCtx);
 
-  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
+  NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
   Bldr.generateNode(CS, Pred, state);
 }
 
 void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
                                     ExplodedNodeSet &Dst) {
-  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
+  NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
 
   // Get the this object region from StoreManager.
   const LocationContext *LCtx = Pred->getLocationContext();
@@ -1226,7 +1226,7 @@ void ExprEngine::VisitLambdaExpr(const LambdaExpr *LE, 
ExplodedNode *Pred,
   SVal LambdaRVal = State->getSVal(R);
 
   ExplodedNodeSet Tmp;
-  StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
+  NodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
   // FIXME: is this the right program point kind?
   Bldr.generateNode(LE, Pred,
                     State->BindExpr(LE, LocCtxt, LambdaRVal),
@@ -1242,7 +1242,7 @@ void ExprEngine::VisitAttributedStmt(const AttributedStmt 
*A,
   getCheckerManager().runCheckersForPreStmt(CheckerPreStmt, Pred, A, *this);
 
   ExplodedNodeSet EvalSet;
-  StmtNodeBuilder Bldr(CheckerPreStmt, EvalSet, *currBldrCtx);
+  NodeBuilder Bldr(CheckerPreStmt, EvalSet, *currBldrCtx);
 
   for (const auto *Attr : getSpecificAttrs<CXXAssumeAttr>(A->getAttrs())) {
     for (ExplodedNode *N : CheckerPreStmt) {
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index ac6c1d76b6b8e..a407a923d7d0f 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -1311,7 +1311,7 @@ void ExprEngine::VisitReturnStmt(const ReturnStmt *RS, 
ExplodedNode *Pred,
   ExplodedNodeSet dstPreVisit;
   getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, RS, *this);
 
-  StmtNodeBuilder B(dstPreVisit, Dst, *currBldrCtx);
+  NodeBuilder B(dstPreVisit, Dst, *currBldrCtx);
 
   if (RS->getRetValue()) {
     for (ExplodedNodeSet::iterator it = dstPreVisit.begin(),
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
index f2e5a163afb62..bb0fd6ded2def 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
@@ -27,7 +27,7 @@ void ExprEngine::VisitLvalObjCIvarRefExpr(const 
ObjCIvarRefExpr *Ex,
   SVal location = state->getLValue(Ex->getDecl(), baseVal);
 
   ExplodedNodeSet dstIvar;
-  StmtNodeBuilder Bldr(Pred, dstIvar, *currBldrCtx);
+  NodeBuilder Bldr(Pred, dstIvar, *currBldrCtx);
   Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, location));
 
   // Perform the post-condition check of the ObjCIvarRefExpr and store
@@ -43,11 +43,13 @@ void ExprEngine::VisitObjCAtSynchronizedStmt(const 
ObjCAtSynchronizedStmt *S,
 
 /// Generate a node in \p Bldr for an iteration statement using ObjC
 /// for-loop iterator.
-static void populateObjCForDestinationSet(
-    ExplodedNodeSet &dstLocation, SValBuilder &svalBuilder,
-    const ObjCForCollectionStmt *S, ConstCFGElementRef elem, SVal elementV,
-    SymbolManager &SymMgr, const NodeBuilderContext *currBldrCtx,
-    StmtNodeBuilder &Bldr, bool hasElements) {
+static void populateObjCForDestinationSet(ExplodedNodeSet &dstLocation,
+                                          SValBuilder &svalBuilder,
+                                          const ObjCForCollectionStmt *S,
+                                          ConstCFGElementRef elem,
+                                          SVal elementV, SymbolManager &SymMgr,
+                                          const NodeBuilderContext 
*currBldrCtx,
+                                          NodeBuilder &Bldr, bool hasElements) 
{
 
   for (ExplodedNode *Pred : dstLocation) {
     ProgramStateRef state = Pred->getState();
@@ -130,7 +132,7 @@ void ExprEngine::VisitObjCForCollectionStmt(const 
ObjCForCollectionStmt *S,
 
   for (ExplodedNode *dstLocation : DstLocation) {
     ExplodedNodeSet DstLocationSingleton{dstLocation}, Tmp;
-    StmtNodeBuilder Bldr(dstLocation, Tmp, *currBldrCtx);
+    NodeBuilder Bldr(dstLocation, Tmp, *currBldrCtx);
 
     if (!isContainerNull)
       populateObjCForDestinationSet(DstLocationSingleton, svalBuilder, S,
@@ -211,7 +213,7 @@ void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME,
       // Receiver is definitely nil, so run ObjCMessageNil callbacks and 
return.
       if (nilState && !notNilState) {
         ExplodedNodeSet dstNil;
-        StmtNodeBuilder Bldr(Pred, dstNil, *currBldrCtx);
+        NodeBuilder Bldr(Pred, dstNil, *currBldrCtx);
         bool HasTag = Pred->getLocation().getTag();
         Pred = Bldr.generateNode(ME, Pred, nilState, nullptr,
                                  ProgramPoint::PreStmtKind);
@@ -229,7 +231,7 @@ void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME,
       }
 
       ExplodedNodeSet dstNonNil;
-      StmtNodeBuilder Bldr(Pred, dstNonNil, *currBldrCtx);
+      NodeBuilder Bldr(Pred, dstNonNil, *currBldrCtx);
       // Generate a transition to the non-nil state, dropping any potential
       // nil flow.
       if (notNilState != State) {
@@ -253,7 +255,7 @@ void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME,
 
   // Proceed with evaluate the message expression.
   ExplodedNodeSet dstEval;
-  StmtNodeBuilder Bldr(dstGenericPrevisit, dstEval, *currBldrCtx);
+  NodeBuilder Bldr(dstGenericPrevisit, dstEval, *currBldrCtx);
 
   for (ExplodedNodeSet::iterator DI = dstGenericPrevisit.begin(),
        DE = dstGenericPrevisit.end(); DI != DE; ++DI) {
diff --git a/clang/test/Analysis/misc-ps-eager-assume.m 
b/clang/test/Analysis/misc-ps-eager-assume.m
index 37395616ee928..f6ae458090715 100644
--- a/clang/test/Analysis/misc-ps-eager-assume.m
+++ b/clang/test/Analysis/misc-ps-eager-assume.m
@@ -132,6 +132,9 @@ void rdar7342806(void) {
 //  Note: CheckerVisit mistakenly cleared an existing node, and the cleared
 //  node was resurrected by GRStmtNodeBuilder::~GRStmtNodeBuilder(), where
 //  'p' was not assigned.
+//  Note 2: This "resurrecting" destructor was removed from the codebase by
+//  commit 320d0b5467b9586a188e06dd2620126f5cb99318 (in 2026) because it was
+//  already dead code at that time.
 //===---------------------------------------------------------------------===//
 
 float *pr5627_f(int y);

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

Reply via email to