https://github.com/NagyDonat created https://github.com/llvm/llvm-project/pull/204371
Part of my commit series to gradually eliminate the class `NodeBuilder`. Admittedly this is one of the few places where the implementation with the `NodeBuilder` is more concise than the new code. This is caused by two factors: 1. This is an optional step in the analysis, so the "put source nodes in destination unless we generate a child node from them" behavior of `NodeBuilder` -- which is often completely useless -- was helpful on two branches. 2. Making nodes with tags is very rare, so I intentionally did not include support for tagging in `makeNodeWithBinding` -- but this is one of the few places where tags are applied. From 14b74b4c8e31bfaeade554220068ae052847cacb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]> Date: Wed, 17 Jun 2026 16:01:09 +0200 Subject: [PATCH 1/2] Introduce name for Pred->getStackFrame() --- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 32da5e097c76e..7996b7ff96d1c 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -3722,6 +3722,7 @@ void ExprEngine::evalEagerlyAssumeBifurcation(ExplodedNodeSet &Dst, NodeBuilder Bldr(Src, Dst, *currBldrCtx); for (ExplodedNode *Pred : Src) { + const StackFrame *SF = Pred->getStackFrame(); // Test if the previous node was as the same expression. This can happen // when the expression fails to evaluate to anything meaningful and // (as an optimization) we don't generate a node. @@ -3732,7 +3733,7 @@ void ExprEngine::evalEagerlyAssumeBifurcation(ExplodedNodeSet &Dst, ProgramStateRef State = Pred->getState(); State = State->set<LastEagerlyAssumeExprIfSuccessful>(nullptr); - SVal V = State->getSVal(Ex, Pred->getStackFrame()); + SVal V = State->getSVal(Ex, SF); std::optional<nonloc::SymbolVal> SEV = V.getAs<nonloc::SymbolVal>(); if (SEV && SEV->isExpression()) { const auto &[TrueTag, FalseTag] = getEagerlyAssumeBifurcationTags(); @@ -3747,14 +3748,14 @@ void ExprEngine::evalEagerlyAssumeBifurcation(ExplodedNodeSet &Dst, // First assume that the condition is true. if (StateTrue) { SVal Val = svalBuilder.makeIntVal(1U, Ex->getType()); - StateTrue = StateTrue->BindExpr(Ex, Pred->getStackFrame(), Val); + StateTrue = StateTrue->BindExpr(Ex, SF, Val); Bldr.generateNode(Ex, Pred, StateTrue, TrueTag); } // Next, assume that the condition is false. if (StateFalse) { SVal Val = svalBuilder.makeIntVal(0U, Ex->getType()); - StateFalse = StateFalse->BindExpr(Ex, Pred->getStackFrame(), Val); + StateFalse = StateFalse->BindExpr(Ex, SF, Val); Bldr.generateNode(Ex, Pred, StateFalse, FalseTag); } } From 3a1fe88b1a540f93f885e81d651c40f6794c77f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]> Date: Wed, 17 Jun 2026 16:06:09 +0200 Subject: [PATCH 2/2] Remove NodeBuilder from eagerly assume logic Admittedly this is one of the few places where the implementation with the `NodeBuilder` is more concise than the new code. This is caused by two factors: 1. This is an optional step in the analysis, so the "put source nodes in destination unless we generate a child node from them" behavior of `NodeBuilder` -- which is often completely useless -- was helpful on two branches. 2. Making nodes with tags is very rare, so I intentionally did not include support for tagging in `makeNodeWithBinding` -- but this is one of the few places where tags are applied. --- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 7996b7ff96d1c..e820f9c12612f 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -3719,8 +3719,6 @@ REGISTER_TRAIT_WITH_PROGRAMSTATE(LastEagerlyAssumeExprIfSuccessful, void ExprEngine::evalEagerlyAssumeBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, const Expr *Ex) { - NodeBuilder Bldr(Src, Dst, *currBldrCtx); - for (ExplodedNode *Pred : Src) { const StackFrame *SF = Pred->getStackFrame(); // Test if the previous node was as the same expression. This can happen @@ -3728,6 +3726,7 @@ void ExprEngine::evalEagerlyAssumeBifurcation(ExplodedNodeSet &Dst, // (as an optimization) we don't generate a node. ProgramPoint P = Pred->getLocation(); if (!P.getAs<PostStmt>() || P.castAs<PostStmt>().getStmt() != Ex) { + Dst.insert(Pred); continue; } @@ -3749,15 +3748,19 @@ void ExprEngine::evalEagerlyAssumeBifurcation(ExplodedNodeSet &Dst, if (StateTrue) { SVal Val = svalBuilder.makeIntVal(1U, Ex->getType()); StateTrue = StateTrue->BindExpr(Ex, SF, Val); - Bldr.generateNode(Ex, Pred, StateTrue, TrueTag); + PostStmt PostStmtTrue(Ex, SF, TrueTag); + Dst.insert(Engine.makeNode(PostStmtTrue, StateTrue, Pred)); } // Next, assume that the condition is false. if (StateFalse) { SVal Val = svalBuilder.makeIntVal(0U, Ex->getType()); StateFalse = StateFalse->BindExpr(Ex, SF, Val); - Bldr.generateNode(Ex, Pred, StateFalse, FalseTag); + PostStmt PostStmtFalse(Ex, SF, FalseTag); + Dst.insert(Engine.makeNode(PostStmtFalse, StateFalse, Pred)); } + } else { + Dst.insert(Pred); } } } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
