[clang] 0037f09 - [NFC][analyzer] Eliminate the NodeBuilder in VisitUnaryOperator (#211304)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 23 03:52:28 PDT 2026
Author: DonĂ¡t Nagy
Date: 2026-07-23T12:52:24+02:00
New Revision: 0037f09f094b0843368df63069b351ec3b952cf8
URL: https://github.com/llvm/llvm-project/commit/0037f09f094b0843368df63069b351ec3b952cf8
DIFF: https://github.com/llvm/llvm-project/commit/0037f09f094b0843368df63069b351ec3b952cf8.diff
LOG: [NFC][analyzer] Eliminate the NodeBuilder in VisitUnaryOperator (#211304)
This is part of the commit series to gradually remove the class
`NodeBuilder` from the analyzer codebase.
This was a relatively complex situation because there were many
different `generateNode` calls and two situations where the the node
from `CheckedSet` was left in `EvalSet` without changes (which is
implicit with the `NodeBuilder` but now requires explicit
`EvalSet.insert(N)` calls).
Added:
Modified:
clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index b50b7f2b05747..b725db1d6256f 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -681,9 +681,6 @@ class ExprEngine {
QualType ExTy, const CastExpr *CastE,
NodeBuilder &Bldr, ExplodedNode *Pred);
- void handleUOExtension(ExplodedNode *N, const UnaryOperator *U,
- NodeBuilder &Bldr);
-
public:
SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op,
SVal LHS, SVal RHS, QualType T) {
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index cee72a792c962..3e7973769f091 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -882,21 +882,6 @@ VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this);
}
-void ExprEngine::handleUOExtension(ExplodedNode *N, const UnaryOperator *U,
- NodeBuilder &Bldr) {
- // FIXME: We can probably just have some magic in Environment::getSVal()
- // that propagates values, instead of creating a new node here.
- //
- // Unary "+" is a no-op, similar to a parentheses. We still have places
- // where it may be a block-level expression, so we need to
- // generate an extra node that just propagates the value of the
- // subexpression.
- const Expr *Ex = U->getSubExpr()->IgnoreParens();
- ProgramStateRef state = N->getState();
- const StackFrame *SF = N->getStackFrame();
- Bldr.generateNode(U, N, state->BindExpr(U, SF, state->getSVal(Ex, SF)));
-}
-
void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
// FIXME: Prechecks eventually go in ::Visit().
@@ -904,15 +889,20 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred,
getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, U, *this);
ExplodedNodeSet EvalSet;
- NodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
+
+ // Lambda for handling the case when the operand is returned unchanged.
+ auto MakeNodeForIdentityOp = [U, &Engine = Engine](ExplodedNode *N) {
+ const Expr *Ex = U->getSubExpr()->IgnoreParens();
+ SVal SV = N->getState()->getSVal(Ex, N->getStackFrame());
+ return Engine.makeNodeWithBinding(N, U, SV);
+ };
for (ExplodedNode *N : CheckedSet) {
switch (U->getOpcode()) {
default: {
- Bldr.takeNodes(N);
ExplodedNodeSet Tmp;
VisitIncrementDecrementOperator(U, N, Tmp);
- Bldr.addNodes(Tmp);
+ EvalSet.insert(Tmp);
break;
}
case UO_Real: {
@@ -921,14 +911,13 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred,
// FIXME: We don't have complex SValues yet.
if (Ex->getType()->isAnyComplexType()) {
// Just report "Unknown."
+ EvalSet.insert(N);
break;
}
// For all other types, UO_Real is an identity operation.
assert (U->getType() == Ex->getType());
- ProgramStateRef state = N->getState();
- const StackFrame *SF = N->getStackFrame();
- Bldr.generateNode(U, N, state->BindExpr(U, SF, state->getSVal(Ex, SF)));
+ EvalSet.insert(MakeNodeForIdentityOp(N));
break;
}
@@ -937,13 +926,12 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred,
// FIXME: We don't have complex SValues yet.
if (Ex->getType()->isAnyComplexType()) {
// Just report "Unknown."
+ EvalSet.insert(N);
break;
}
// For all other types, UO_Imag returns 0.
- ProgramStateRef state = N->getState();
- const StackFrame *SF = N->getStackFrame();
SVal X = svalBuilder.makeZeroVal(Ex->getType());
- Bldr.generateNode(U, N, state->BindExpr(U, SF, X));
+ EvalSet.insert(Engine.makeNodeWithBinding(N, U, X));
break;
}
@@ -954,15 +942,13 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred,
const ValueDecl *VD = DRE->getDecl();
if (isa<CXXMethodDecl, FieldDecl, IndirectFieldDecl>(VD)) {
- ProgramStateRef State = N->getState();
- const StackFrame *SF = N->getStackFrame();
SVal SV = svalBuilder.getMemberPointer(cast<NamedDecl>(VD));
- Bldr.generateNode(U, N, State->BindExpr(U, SF, SV));
+ EvalSet.insert(Engine.makeNodeWithBinding(N, U, SV));
break;
}
}
// Explicitly proceed with default handler for this case cascade.
- handleUOExtension(N, U, Bldr);
+ EvalSet.insert(MakeNodeForIdentityOp(N));
break;
}
case UO_Plus:
@@ -970,7 +956,7 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred,
[[fallthrough]];
case UO_Deref:
case UO_Extension: {
- handleUOExtension(N, U, Bldr);
+ EvalSet.insert(MakeNodeForIdentityOp(N));
break;
}
@@ -986,7 +972,7 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred,
SVal V = state->getSVal(Ex, SF);
if (V.isUnknownOrUndef()) {
- Bldr.generateNode(U, N, state->BindExpr(U, SF, V));
+ EvalSet.insert(Engine.makeNodeWithBinding(N, U, V));
break;
}
@@ -1023,7 +1009,7 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred,
state = state->BindExpr(U, SF, Result);
break;
}
- Bldr.generateNode(U, N, state);
+ EvalSet.insert(Engine.makePostStmtNode(U, state, N));
break;
}
}
More information about the cfe-commits
mailing list