[clang] [NFC][analyzer] Refactor Environment to map Expr to SVal instead of Stmt to SVal (PR #193295)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Apr 25 11:56:31 PDT 2026
=?utf-8?b?R8OhYm9yIFTDs3RodsOhcmk=?=,=?utf-8?b?R8OhYm9yIFTDs3RodsOhcmk=?=,
=?utf-8?b?R8OhYm9yIFTDs3RodsOhcmk=?=,=?utf-8?b?R8OhYm9yIFTDs3RodsOhcmk=?=,
=?utf-8?b?R8OhYm9yIFTDs3RodsOhcmk=?=,tigbr <tigbrcode at protonmail.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/193295 at github.com>
https://github.com/tigbr updated https://github.com/llvm/llvm-project/pull/193295
>From 806b3193117c756db097065594c5c3350e7e1a98 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=A1bor=20T=C3=B3thv=C3=A1ri?=
<gabor.tothvari at ericsson.com>
Date: Sat, 28 Mar 2026 08:03:44 +0100
Subject: [PATCH 1/7] [NFC][analyzer] Refactor Environment to map Expr to SVal
instead of Stmt to SVal
The Environment now maps expressions to symbolic values at the type level.
Handling of return statements has been moved to the ExprEngine from
the Environment. Type signatures have been updated and dynamic casts
were introduced where it was necessary.
---
.../clang/StaticAnalyzer/Checkers/Taint.h | 8 ++--
.../Core/PathSensitive/CallEvent.h | 4 +-
.../Core/PathSensitive/CheckerContext.h | 4 +-
.../Core/PathSensitive/Environment.h | 13 ++---
.../Core/PathSensitive/ExplodedGraph.h | 4 +-
.../Core/PathSensitive/ProgramState.h | 20 ++++----
.../Checkers/BasicObjCFoundationChecks.cpp | 7 ++-
.../StaticAnalyzer/Checkers/MIGChecker.cpp | 2 +-
.../Checkers/NullabilityChecker.cpp | 2 +-
.../RetainCountChecker/RetainCountChecker.cpp | 3 +-
.../RetainCountDiagnostics.cpp | 3 +-
clang/lib/StaticAnalyzer/Checkers/Taint.cpp | 14 +++---
.../Checkers/TestAfterDivZeroChecker.cpp | 2 +-
.../Checkers/UndefBranchChecker.cpp | 8 +++-
.../Core/BugReporterVisitors.cpp | 9 ++--
clang/lib/StaticAnalyzer/Core/Environment.cpp | 48 ++++---------------
clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 21 ++++----
.../Core/ExprEngineCallAndReturn.cpp | 10 ++--
.../StaticAnalyzer/Core/ExprEngineObjC.cpp | 10 ++--
19 files changed, 88 insertions(+), 104 deletions(-)
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Taint.h b/clang/include/clang/StaticAnalyzer/Checkers/Taint.h
index 3ec8dbfb09ee3..461fe059071d4 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Taint.h
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Taint.h
@@ -27,7 +27,7 @@ using TaintTagType = unsigned;
static constexpr TaintTagType TaintTagGeneric = 0;
/// Create a new state in which the value of the statement is marked as tainted.
-[[nodiscard]] ProgramStateRef addTaint(ProgramStateRef State, const Stmt *S,
+[[nodiscard]] ProgramStateRef addTaint(ProgramStateRef State, const Expr *Ex,
const LocationContext *LCtx,
TaintTagType Kind = TaintTagGeneric);
@@ -62,7 +62,7 @@ addPartialTaint(ProgramStateRef State, SymbolRef ParentSym,
TaintTagType Kind = TaintTagGeneric);
/// Check if the statement has a tainted value in the given state.
-bool isTainted(ProgramStateRef State, const Stmt *S,
+bool isTainted(ProgramStateRef State, const Expr *Ex,
const LocationContext *LCtx,
TaintTagType Kind = TaintTagGeneric);
@@ -80,7 +80,7 @@ bool isTainted(ProgramStateRef State, const MemRegion *Reg,
TaintTagType Kind = TaintTagGeneric);
/// Returns the tainted Symbols for a given Statement and state.
-std::vector<SymbolRef> getTaintedSymbols(ProgramStateRef State, const Stmt *S,
+std::vector<SymbolRef> getTaintedSymbols(ProgramStateRef State, const Expr *Ex,
const LocationContext *LCtx,
TaintTagType Kind = TaintTagGeneric);
@@ -99,7 +99,7 @@ std::vector<SymbolRef> getTaintedSymbols(ProgramStateRef State,
TaintTagType Kind = TaintTagGeneric);
std::vector<SymbolRef> getTaintedSymbolsImpl(ProgramStateRef State,
- const Stmt *S,
+ const Expr *Ex,
const LocationContext *LCtx,
TaintTagType Kind,
bool returnFirstOnly);
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index 0b9202bcf274e..a855ef0381056 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -199,8 +199,8 @@ class CallEvent {
virtual void cloneTo(void *Dest) const = 0;
/// Get the value of arbitrary expressions at this point in the path.
- SVal getSVal(const Stmt *S) const {
- return getState()->getSVal(S, getLocationContext());
+ SVal getSVal(const Expr *Ex) const {
+ return getState()->getSVal(Ex, getLocationContext());
}
using ValueList = SmallVectorImpl<SVal>;
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index 818a54eec48e5..00cdf1fd33c08 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -168,8 +168,8 @@ class CheckerContext {
}
/// Get the value of arbitrary expressions at this point in the path.
- SVal getSVal(const Stmt *S) const {
- return Pred->getSVal(S);
+ SVal getSVal(const Expr *Ex) const {
+ return Pred->getSVal(Ex);
}
ConstCFGElementRef getCFGElementRef() const { return Eng.getCFGElementRef(); }
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
index 56453df79819e..2430c3e305a16 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
@@ -32,23 +32,18 @@ class SymbolReaper;
/// This allows the environment to manage context-sensitive bindings,
/// which is essentially for modeling recursive function analysis, among
/// other things.
-/// FIXME: Use 'Expr' instead of 'Stmt' because associating a result with a
-/// non-expression statement does not make sense. Currently the environment
-/// only containts 'Expr's; and there is only one easy-to-eliminate hack in
-/// 'processCallExit' and 'Environment::getSVal' that constructs and handles
-/// 'EnvironmentEntry' instances with a 'ReturnStmt' as the 'first' part.
-class EnvironmentEntry : public std::pair<const Stmt *,
+class EnvironmentEntry : public std::pair<const Expr *,
const StackFrameContext *> {
public:
- EnvironmentEntry(const Stmt *s, const LocationContext *L);
+ EnvironmentEntry(const Expr *Ex, const LocationContext *L);
- const Stmt *getStmt() const { return first; }
+ const Expr *getExpr() const { return first; }
const LocationContext *getLocationContext() const { return second; }
/// Profile an EnvironmentEntry for inclusion in a FoldingSet.
static void Profile(llvm::FoldingSetNodeID &ID,
const EnvironmentEntry &E) {
- ID.AddPointer(E.getStmt());
+ ID.AddPointer(E.getExpr());
ID.AddPointer(E.getLocationContext());
}
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index 2988b1bbad68f..a359f9259c6e4 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -169,8 +169,8 @@ class ExplodedNode : public llvm::FoldingSetNode {
}
/// Get the value of an arbitrary expression at this node.
- SVal getSVal(const Stmt *S) const {
- return getState()->getSVal(S, getLocationContext());
+ SVal getSVal(const Expr *Ex) const {
+ return getState()->getSVal(Ex, getLocationContext());
}
static void Profile(llvm::FoldingSetNodeID &ID,
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index 942f5544c2b2e..575f70aa87c01 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -377,10 +377,10 @@ class ProgramState : public llvm::FoldingSetNode {
/// Get the lvalue for an array index.
SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const;
- /// Returns the SVal bound to the statement 'S' in the state's environment.
- SVal getSVal(const Stmt *S, const LocationContext *LCtx) const;
+ /// Returns the SVal bound to the expression 'E' in the state's environment.
+ SVal getSVal(const Expr *E, const LocationContext *LCtx) const;
- SVal getSValAsScalarOrLoc(const Stmt *Ex, const LocationContext *LCtx) const;
+ SVal getSValAsScalarOrLoc(const Expr *Ex, const LocationContext *LCtx) const;
/// Return the value bound to the specified location.
/// Returns UnknownVal() if none found.
@@ -792,22 +792,18 @@ inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) c
return UnknownVal();
}
-inline SVal ProgramState::getSVal(const Stmt *Ex,
+inline SVal ProgramState::getSVal(const Expr *Ex,
const LocationContext *LCtx) const{
return Env.getSVal(EnvironmentEntry(Ex, LCtx),
*getStateManager().svalBuilder);
}
inline SVal
-ProgramState::getSValAsScalarOrLoc(const Stmt *S,
+ProgramState::getSValAsScalarOrLoc(const Expr *Ex,
const LocationContext *LCtx) const {
- if (const Expr *Ex = dyn_cast<Expr>(S)) {
- QualType T = Ex->getType();
- if (Ex->isGLValue() || Loc::isLocType(T) ||
- T->isIntegralOrEnumerationType())
- return getSVal(S, LCtx);
- }
-
+ QualType T = Ex->getType();
+ if (Ex->isGLValue() || Loc::isLocType(T) || T->isIntegralOrEnumerationType())
+ return getSVal(Ex, LCtx);
return UnknownVal();
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
index f226f80aa441f..810c299a363a6 100644
--- a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -886,7 +886,12 @@ static ProgramStateRef checkElementNonNil(CheckerContext &C,
assert(ElemDecl->getInit() == nullptr);
ElementLoc = State->getLValue(ElemDecl, LCtx);
} else {
- ElementLoc = State->getSVal(Element, LCtx).getAs<Loc>();
+ const Expr *Ex = dyn_cast<Expr>(Element);
+ if (Ex) {
+ ElementLoc = State->getSVal(Ex, LCtx).getAs<Loc>();
+ } else {
+ ElementLoc = UnknownVal().getAs<Loc>();
+ }
}
if (!ElementLoc)
diff --git a/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp
index bb4446df87dbb..2ac9ae0e4b806 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp
@@ -270,7 +270,7 @@ void MIGChecker::checkReturnAux(const ReturnStmt *RS, CheckerContext &C) const {
if (!State->get<ReleasedParameter>())
return;
- SVal V = C.getSVal(RS);
+ SVal V = RS->getRetValue() ? C.getSVal(RS->getRetValue()) : UndefinedVal();
if (mayBeSuccess(V, C))
return;
diff --git a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
index 2746083431dce..06a9415b79f3f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
@@ -661,7 +661,7 @@ void NullabilityChecker::checkPreStmt(const ReturnStmt *S,
if (State->get<InvariantViolated>())
return;
- auto RetSVal = C.getSVal(S).getAs<DefinedOrUnknownSVal>();
+ auto RetSVal = C.getSVal(RetExpr).getAs<DefinedOrUnknownSVal>();
if (!RetSVal)
return;
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index 1762505f58f0f..f4fc5e5da03f5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -229,7 +229,8 @@ void RetainCountChecker::processObjCLiterals(CheckerContext &C,
ProgramStateRef state = C.getState();
const ExplodedNode *pred = C.getPredecessor();
for (const Stmt *Child : Ex->children()) {
- SVal V = pred->getSVal(Child);
+ const Expr *ChildAsExpr = dyn_cast<Expr>(Child);
+ SVal V = ChildAsExpr ? pred->getSVal(ChildAsExpr) : UnknownVal();
if (SymbolRef sym = V.getAsSymbol())
if (const RefVal* T = getRefBinding(state, sym)) {
RefVal::Kind hasErr = (RefVal::Kind) 0;
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
index cad2c72438d4a..eb56fb190e762 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -660,8 +660,7 @@ static AllocationInfo GetAllocationSite(ProgramStateManager &StateMgr,
if (auto CEP = N->getLocation().getAs<CallEnter>()) {
const Stmt *CE = CEP->getCallExpr();
if (const auto *ME = dyn_cast_or_null<ObjCMessageExpr>(CE)) {
- const Stmt *RecExpr = ME->getInstanceReceiver();
- if (RecExpr) {
+ if (const Expr *RecExpr = ME->getInstanceReceiver()) {
SVal RecV = St->getSVal(RecExpr, NContext);
if (ME->getMethodFamily() == OMF_init && RecV.getAsSymbol() == Sym)
InitMethodContext = CEP->getCalleeContext();
diff --git a/clang/lib/StaticAnalyzer/Checkers/Taint.cpp b/clang/lib/StaticAnalyzer/Checkers/Taint.cpp
index e55d064253b84..eef69c0677025 100644
--- a/clang/lib/StaticAnalyzer/Checkers/Taint.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/Taint.cpp
@@ -43,10 +43,10 @@ void taint::dumpTaint(ProgramStateRef State) {
printTaint(State, llvm::errs());
}
-ProgramStateRef taint::addTaint(ProgramStateRef State, const Stmt *S,
+ProgramStateRef taint::addTaint(ProgramStateRef State, const Expr *Ex,
const LocationContext *LCtx,
TaintTagType Kind) {
- return addTaint(State, State->getSVal(S, LCtx), Kind);
+ return addTaint(State, State->getSVal(Ex, LCtx), Kind);
}
ProgramStateRef taint::addTaint(ProgramStateRef State, SVal V,
@@ -145,9 +145,9 @@ ProgramStateRef taint::addPartialTaint(ProgramStateRef State,
return NewState;
}
-bool taint::isTainted(ProgramStateRef State, const Stmt *S,
+bool taint::isTainted(ProgramStateRef State, const Expr *Ex,
const LocationContext *LCtx, TaintTagType Kind) {
- return !getTaintedSymbolsImpl(State, S, LCtx, Kind, /*ReturnFirstOnly=*/true)
+ return !getTaintedSymbolsImpl(State, Ex, LCtx, Kind, /*ReturnFirstOnly=*/true)
.empty();
}
@@ -168,7 +168,7 @@ bool taint::isTainted(ProgramStateRef State, SymbolRef Sym, TaintTagType Kind) {
}
std::vector<SymbolRef> taint::getTaintedSymbols(ProgramStateRef State,
- const Stmt *S,
+ const Expr *S,
const LocationContext *LCtx,
TaintTagType Kind) {
return getTaintedSymbolsImpl(State, S, LCtx, Kind, /*ReturnFirstOnly=*/false);
@@ -192,11 +192,11 @@ std::vector<SymbolRef> taint::getTaintedSymbols(ProgramStateRef State,
}
std::vector<SymbolRef> taint::getTaintedSymbolsImpl(ProgramStateRef State,
- const Stmt *S,
+ const Expr *Ex,
const LocationContext *LCtx,
TaintTagType Kind,
bool returnFirstOnly) {
- SVal val = State->getSVal(S, LCtx);
+ SVal val = State->getSVal(Ex, LCtx);
return getTaintedSymbolsImpl(State, val, Kind, returnFirstOnly);
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp
index 77cec7deffb84..f69e373e0944d 100644
--- a/clang/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp
@@ -242,7 +242,7 @@ void TestAfterDivZeroChecker::checkBranchCondition(const Stmt *Condition,
if (hasDivZeroMap(Val, C))
reportBug(Val, C);
else {
- SVal Val = C.getSVal(Condition);
+ SVal Val = C.getSVal(IE);
if (hasDivZeroMap(Val, C))
reportBug(Val, C);
diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
index aa478b69aade1..255624968fffc 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
@@ -64,7 +64,12 @@ void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
// ObjCForCollection is a loop, but has no actual condition.
if (isa<ObjCForCollectionStmt>(Condition))
return;
- if (!Ctx.getSVal(Condition).isUndef())
+
+ const Expr *Ex = dyn_cast<Expr>(Condition);
+ if (!Ex)
+ return;
+
+ if (!Ctx.getSVal(Ex).isUndef())
return;
// Generate a sink node, which implicitly marks both outgoing branches as
@@ -87,7 +92,6 @@ void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
// since all the BlockEdge did was act as an error sink since the value
// had to already be undefined.
assert(!N->pred_empty());
- const Expr *Ex = cast<Expr>(Condition);
ExplodedNode *PrevN = *N->pred_begin();
ProgramPoint P = PrevN->getLocation();
ProgramStateRef St = N->getState();
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index 7df5fab0843ac..bcfa2a38bed4f 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -949,7 +949,10 @@ class ReturnVisitor : public TrackingBugReporterVisitor {
// Okay, we're at the right return statement, but do we have the return
// value available?
ProgramStateRef State = N->getState();
- SVal V = State->getSVal(Ret, CalleeSFC);
+ const Expr *RV = Ret->getRetValue();
+ if (!RV)
+ return nullptr;
+ SVal V = State->getSVal(RV, CalleeSFC);
if (V.isUnknownOrUndef())
return nullptr;
@@ -1737,12 +1740,12 @@ PathDiagnosticPieceRef StoreSiteFinder::VisitNode(const ExplodedNode *Succ,
if (DS) {
SI.StoreKind = StoreInfo::Initialization;
- } else if (isa<BlockExpr>(S)) {
+ } else if (const BlockExpr *BExpr = dyn_cast<BlockExpr>(S)) {
SI.StoreKind = StoreInfo::BlockCapture;
if (VR) {
// See if we can get the BlockVarRegion.
ProgramStateRef State = StoreSite->getState();
- SVal V = StoreSite->getSVal(S);
+ SVal V = StoreSite->getSVal(BExpr);
if (const auto *BDR =
dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
if (const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) {
diff --git a/clang/lib/StaticAnalyzer/Core/Environment.cpp b/clang/lib/StaticAnalyzer/Core/Environment.cpp
index bfe973afc3210..9f89382d0c95b 100644
--- a/clang/lib/StaticAnalyzer/Core/Environment.cpp
+++ b/clang/lib/StaticAnalyzer/Core/Environment.cpp
@@ -63,14 +63,8 @@ static const Expr *ignoreTransparentExprs(const Expr *E) {
return ignoreTransparentExprs(E);
}
-static const Stmt *ignoreTransparentExprs(const Stmt *S) {
- if (const auto *E = dyn_cast<Expr>(S))
- return ignoreTransparentExprs(E);
- return S;
-}
-
-EnvironmentEntry::EnvironmentEntry(const Stmt *S, const LocationContext *L)
- : std::pair<const Stmt *,
+EnvironmentEntry::EnvironmentEntry(const Expr *S, const LocationContext *L)
+ : std::pair<const Expr *,
const StackFrameContext *>(ignoreTransparentExprs(S),
L ? L->getStackFrame()
: nullptr) {}
@@ -86,16 +80,10 @@ SVal Environment::lookupExpr(const EnvironmentEntry &E) const {
SVal Environment::getSVal(const EnvironmentEntry &Entry,
SValBuilder& svalBuilder) const {
- const Stmt *S = Entry.getStmt();
- assert(!isa<ObjCForCollectionStmt>(S) &&
- "Use ExprEngine::hasMoreIteration()!");
- assert((isa<Expr, ReturnStmt>(S)) &&
- "Environment can only argue about Exprs, since only they express "
- "a value! Any non-expression statement stored in Environment is a "
- "result of a hack!");
+ const Expr *Ex = Entry.getExpr();
const LocationContext *LCtx = Entry.getLocationContext();
- switch (S->getStmtClass()) {
+ switch (Ex->getStmtClass()) {
case Stmt::CXXBindTemporaryExprClass:
case Stmt::ExprWithCleanupsClass:
case Stmt::GenericSelectionExprClass:
@@ -118,23 +106,11 @@ SVal Environment::getSVal(const EnvironmentEntry &Entry,
case Stmt::SizeOfPackExprClass:
case Stmt::PredefinedExprClass:
// Known constants; defer to SValBuilder.
- return *svalBuilder.getConstantVal(cast<Expr>(S));
-
- case Stmt::ReturnStmtClass: {
- // FIXME: Move this logic to ExprEngine::processCallExit (the only location
- // passes a ReturnStmt to this method) and then there will be no need to
- // accept non-expression statements in getSVal (in fact, it will be
- // possible to change the first member of EnvironmentEntry from const Stmt*
- // to const Expr*).
- const auto *RS = cast<ReturnStmt>(S);
- if (const Expr *RE = RS->getRetValue())
- return getSVal(EnvironmentEntry(RE, LCtx), svalBuilder);
- return UndefinedVal();
- }
+ return *svalBuilder.getConstantVal(Ex);
- // Handle all other Stmt* using a lookup.
+ // Handle all other Expr* using a lookup.
default:
- return lookupExpr(EnvironmentEntry(S, LCtx));
+ return lookupExpr(EnvironmentEntry(Ex, LCtx));
}
}
@@ -200,11 +176,7 @@ EnvironmentManager::removeDeadBindings(Environment Env,
const EnvironmentEntry &BlkExpr = I.getKey();
SVal X = I.getData();
- const Expr *E = dyn_cast<Expr>(BlkExpr.getStmt());
- if (!E)
- continue;
-
- if (SymReaper.isLive(E, BlkExpr.getLocationContext())) {
+ if (SymReaper.isLive(BlkExpr.getExpr(), BlkExpr.getLocationContext())) {
// Copy the binding to the new map.
EBMapRef = EBMapRef.add(BlkExpr, X);
@@ -265,7 +237,7 @@ void Environment::printJson(raw_ostream &Out, const ASTContext &Ctx,
Out << '[' << NL;
}
- const Stmt *S = I->first.getStmt();
+ const Stmt *S = I->first.getExpr();
(void)S;
assert(S != nullptr && "Expected non-null Stmt");
@@ -277,7 +249,7 @@ void Environment::printJson(raw_ostream &Out, const ASTContext &Ctx,
if (I->first.getLocationContext() != LC)
continue;
- const Stmt *S = I->first.getStmt();
+ const Stmt *S = I->first.getExpr();
Indent(Out, InnerSpace, IsDot)
<< "{ \"stmt_id\": " << S->getID(Ctx) << ", \"kind\": \""
<< S->getStmtClassName() << "\", \"pretty\": ";
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index b69b45acb7989..a46485f858fac 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1411,7 +1411,7 @@ void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor,
ProgramStateRef State = Pred->getState();
const LocationContext *LCtx = Pred->getLocationContext();
const CXXDeleteExpr *DE = Dtor.getDeleteExpr();
- const Stmt *Arg = DE->getArgument();
+ const Expr *Arg = DE->getArgument();
QualType DTy = DE->getDestroyedType();
SVal ArgVal = State->getSVal(Arg, LCtx);
@@ -2061,7 +2061,8 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
->getType()->isRecordType()))
for (auto Child : Ex->children()) {
assert(Child);
- SVal Val = State->getSVal(Child, LCtx);
+ const Expr *ChildExpr = dyn_cast<Expr>(Child);
+ SVal Val = ChildExpr ? State->getSVal(ChildExpr, LCtx) : UnknownVal();
State = escapeValues(State, Val, PSK_EscapeOther);
}
@@ -2780,9 +2781,9 @@ bool ExprEngine::hasMoreIteration(ProgramStateRef State,
/// Returns a (HasMoreIteration, HasNoMoreIteration) pair, or std::nullopt when
/// the acquisition of the loop condition value failed.
static std::optional<std::pair<ProgramStateRef, ProgramStateRef>>
-assumeCondition(const Stmt *Condition, ExplodedNode *N) {
+assumeCondition(const Stmt *ConditionStmt, ExplodedNode *N) {
ProgramStateRef State = N->getState();
- if (const auto *ObjCFor = dyn_cast<ObjCForCollectionStmt>(Condition)) {
+ if (const auto *ObjCFor = dyn_cast<ObjCForCollectionStmt>(ConditionStmt)) {
bool HasMoreIteraton =
ExprEngine::hasMoreIteration(State, ObjCFor, N->getLocationContext());
// Checkers have already ran on branch conditions, so the current
@@ -2795,18 +2796,22 @@ assumeCondition(const Stmt *Condition, ExplodedNode *N) {
else
return std::pair<ProgramStateRef, ProgramStateRef>{nullptr, State};
}
- SVal X = State->getSVal(Condition, N->getLocationContext());
+
+ const Expr *ConditionExpr = dyn_cast<Expr>(ConditionStmt);
+ assert(ConditionExpr && "The condition must be an Expr from here!");
+
+ SVal X = State->getSVal(ConditionExpr, N->getLocationContext());
if (X.isUnknownOrUndef()) {
// Give it a chance to recover from unknown.
- if (const auto *Ex = dyn_cast<Expr>(Condition)) {
+ if (const auto *Ex = dyn_cast<Expr>(ConditionExpr)) {
if (Ex->getType()->isIntegralOrEnumerationType()) {
// Try to recover some path-sensitivity. Right now casts of symbolic
// integers that promote their values are currently not tracked well.
- // If 'Condition' is such an expression, try and recover the
+ // If 'ConditionExpr' is such an expression, try and recover the
// underlying value and use that instead.
SVal recovered =
- RecoverCastedSymbol(State, Condition, N->getLocationContext(),
+ RecoverCastedSymbol(State, ConditionExpr, N->getLocationContext(),
N->getState()->getStateManager().getContext());
if (!recovered.isUnknown()) {
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 3dc3c9d05f24e..20f836d722827 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -301,15 +301,15 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
// which is special cased to look up the subexpression RS->getRetValue()
// in environment. Instead of relying on this hack, pass
// RS->getRetValue() to getSVal() after checking it for nullness.
- SVal V = State->getSVal(RS, LCtx);
+ SVal V = UndefinedVal();
+ if (RS->getRetValue())
+ V = State->getSVal(RS->getRetValue(), LCtx);
// Ensure that the return type matches the type of the returned Expr.
if (wasDifferentDeclUsedForInlining(Call, CalleeCtx)) {
- QualType ReturnedTy =
- CallEvent::getDeclaredResultType(CalleeCtx->getDecl());
+ QualType ReturnedTy = CallEvent::getDeclaredResultType(CalleeCtx->getDecl());
if (!ReturnedTy.isNull()) {
- V = adjustReturnValue(V, CE->getType(), ReturnedTy,
- getStoreManager());
+ V = adjustReturnValue(V, CE->getType(), ReturnedTy, getStoreManager());
}
}
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
index 07703bdf38239..70c0ce8af70bd 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
@@ -111,18 +111,22 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
// result in state splitting.
const Stmt *elem = S->getElement();
- const Stmt *collection = S->getCollection();
+ const Expr *collection = S->getCollection();
const ConstCFGElementRef &elemRef = getCFGElementRef();
ProgramStateRef state = Pred->getState();
+
SVal collectionV = state->getSVal(collection, Pred->getLocationContext());
- SVal elementV;
+ SVal elementV = UnknownVal();
if (const auto *DS = dyn_cast<DeclStmt>(elem)) {
const VarDecl *elemD = cast<VarDecl>(DS->getSingleDecl());
assert(elemD->getInit() == nullptr);
elementV = state->getLValue(elemD, Pred->getLocationContext());
} else {
- elementV = state->getSVal(elem, Pred->getLocationContext());
+ const Expr *Ex = dyn_cast<Expr>(elem);
+ if (Ex) {
+ elementV = state->getSVal(Ex, Pred->getLocationContext());
+ }
}
bool isContainerNull = state->isNull(collectionV).isConstrainedTrue();
>From 1a3faec6e5ad1282d7ec7506434bd35c7e6ac0ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=A1bor=20T=C3=B3thv=C3=A1ri?=
<gabor.tothvari at ericsson.com>
Date: Wed, 22 Apr 2026 16:18:39 +0200
Subject: [PATCH 2/7] Renames
---
.../include/clang/StaticAnalyzer/Checkers/Taint.h | 6 +++---
.../Core/PathSensitive/ProgramState.h | 4 ++--
clang/lib/StaticAnalyzer/Checkers/Taint.cpp | 4 ++--
clang/lib/StaticAnalyzer/Core/Environment.cpp | 14 +++++++-------
4 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Taint.h b/clang/include/clang/StaticAnalyzer/Checkers/Taint.h
index 461fe059071d4..0145973c3b951 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Taint.h
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Taint.h
@@ -26,7 +26,7 @@ using TaintTagType = unsigned;
static constexpr TaintTagType TaintTagGeneric = 0;
-/// Create a new state in which the value of the statement is marked as tainted.
+/// Create a new state in which the value of the expression is marked as tainted.
[[nodiscard]] ProgramStateRef addTaint(ProgramStateRef State, const Expr *Ex,
const LocationContext *LCtx,
TaintTagType Kind = TaintTagGeneric);
@@ -61,7 +61,7 @@ addPartialTaint(ProgramStateRef State, SymbolRef ParentSym,
const SubRegion *SubRegion,
TaintTagType Kind = TaintTagGeneric);
-/// Check if the statement has a tainted value in the given state.
+/// Check if the expression has a tainted value in the given state.
bool isTainted(ProgramStateRef State, const Expr *Ex,
const LocationContext *LCtx,
TaintTagType Kind = TaintTagGeneric);
@@ -79,7 +79,7 @@ bool isTainted(ProgramStateRef State, SymbolRef Sym,
bool isTainted(ProgramStateRef State, const MemRegion *Reg,
TaintTagType Kind = TaintTagGeneric);
-/// Returns the tainted Symbols for a given Statement and state.
+/// Returns the tainted Symbols for a given expression and state.
std::vector<SymbolRef> getTaintedSymbols(ProgramStateRef State, const Expr *Ex,
const LocationContext *LCtx,
TaintTagType Kind = TaintTagGeneric);
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index 575f70aa87c01..f6d1909417c28 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -377,8 +377,8 @@ class ProgramState : public llvm::FoldingSetNode {
/// Get the lvalue for an array index.
SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const;
- /// Returns the SVal bound to the expression 'E' in the state's environment.
- SVal getSVal(const Expr *E, const LocationContext *LCtx) const;
+ /// Returns the SVal bound to the expression \p Ex in the state's environment.
+ SVal getSVal(const Expr *Ex, const LocationContext *LCtx) const;
SVal getSValAsScalarOrLoc(const Expr *Ex, const LocationContext *LCtx) const;
diff --git a/clang/lib/StaticAnalyzer/Checkers/Taint.cpp b/clang/lib/StaticAnalyzer/Checkers/Taint.cpp
index eef69c0677025..0606b7efc0d8e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/Taint.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/Taint.cpp
@@ -168,10 +168,10 @@ bool taint::isTainted(ProgramStateRef State, SymbolRef Sym, TaintTagType Kind) {
}
std::vector<SymbolRef> taint::getTaintedSymbols(ProgramStateRef State,
- const Expr *S,
+ const Expr *Ex,
const LocationContext *LCtx,
TaintTagType Kind) {
- return getTaintedSymbolsImpl(State, S, LCtx, Kind, /*ReturnFirstOnly=*/false);
+ return getTaintedSymbolsImpl(State, Ex, LCtx, Kind, /*ReturnFirstOnly=*/false);
}
std::vector<SymbolRef> taint::getTaintedSymbols(ProgramStateRef State, SVal V,
diff --git a/clang/lib/StaticAnalyzer/Core/Environment.cpp b/clang/lib/StaticAnalyzer/Core/Environment.cpp
index 9f89382d0c95b..14fa9b1024fdd 100644
--- a/clang/lib/StaticAnalyzer/Core/Environment.cpp
+++ b/clang/lib/StaticAnalyzer/Core/Environment.cpp
@@ -237,9 +237,9 @@ void Environment::printJson(raw_ostream &Out, const ASTContext &Ctx,
Out << '[' << NL;
}
- const Stmt *S = I->first.getExpr();
- (void)S;
- assert(S != nullptr && "Expected non-null Stmt");
+ const Expr *Ex = I->first.getExpr();
+ (void)Ex;
+ assert(Ex != nullptr && "Expected non-null Expr");
LastI = I;
}
@@ -249,11 +249,11 @@ void Environment::printJson(raw_ostream &Out, const ASTContext &Ctx,
if (I->first.getLocationContext() != LC)
continue;
- const Stmt *S = I->first.getExpr();
+ const Expr *Ex = I->first.getExpr();
Indent(Out, InnerSpace, IsDot)
- << "{ \"stmt_id\": " << S->getID(Ctx) << ", \"kind\": \""
- << S->getStmtClassName() << "\", \"pretty\": ";
- S->printJson(Out, nullptr, PP, /*AddQuotes=*/true);
+ << "{ \"stmt_id\": " << Ex->getID(Ctx) << ", \"kind\": \""
+ << Ex->getStmtClassName() << "\", \"pretty\": ";
+ Ex->printJson(Out, nullptr, PP, /*AddQuotes=*/true);
Out << ", \"value\": ";
I->second.printJson(Out, /*AddQuotes=*/true);
>From 86afedd4e8c45d38b2cbe90ac97ca4456896022a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=A1bor=20T=C3=B3thv=C3=A1ri?=
<gabor.tothvari at ericsson.com>
Date: Wed, 22 Apr 2026 16:21:07 +0200
Subject: [PATCH 3/7] Simplify else conditions
---
.../Checkers/BasicObjCFoundationChecks.cpp | 9 ++-------
clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp | 7 ++-----
2 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
index 810c299a363a6..e8c14c4eb803c 100644
--- a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -885,13 +885,8 @@ static ProgramStateRef checkElementNonNil(CheckerContext &C,
const VarDecl *ElemDecl = cast<VarDecl>(DS->getSingleDecl());
assert(ElemDecl->getInit() == nullptr);
ElementLoc = State->getLValue(ElemDecl, LCtx);
- } else {
- const Expr *Ex = dyn_cast<Expr>(Element);
- if (Ex) {
- ElementLoc = State->getSVal(Ex, LCtx).getAs<Loc>();
- } else {
- ElementLoc = UnknownVal().getAs<Loc>();
- }
+ } else if (const auto *Ex = dyn_cast<Expr>(Element)) {
+ ElementLoc = State->getSVal(Ex, LCtx).getAs<Loc>();
}
if (!ElementLoc)
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
index 70c0ce8af70bd..e4914782acb2f 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
@@ -122,11 +122,8 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
const VarDecl *elemD = cast<VarDecl>(DS->getSingleDecl());
assert(elemD->getInit() == nullptr);
elementV = state->getLValue(elemD, Pred->getLocationContext());
- } else {
- const Expr *Ex = dyn_cast<Expr>(elem);
- if (Ex) {
- elementV = state->getSVal(Ex, Pred->getLocationContext());
- }
+ } else if (const auto *Ex = dyn_cast<Expr>(elem)) {
+ elementV = state->getSVal(Ex, Pred->getLocationContext());
}
bool isContainerNull = state->isNull(collectionV).isConstrainedTrue();
>From 5364bb1f7c20489810f6ceb834abada8dee9a0f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=A1bor=20T=C3=B3thv=C3=A1ri?=
<gabor.tothvari at ericsson.com>
Date: Wed, 22 Apr 2026 16:46:42 +0200
Subject: [PATCH 4/7] Formatting
---
clang/include/clang/StaticAnalyzer/Checkers/Taint.h | 3 ++-
.../StaticAnalyzer/Core/PathSensitive/CheckerContext.h | 4 +---
.../clang/StaticAnalyzer/Core/PathSensitive/Environment.h | 4 ++--
.../clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h | 2 +-
clang/lib/StaticAnalyzer/Checkers/Taint.cpp | 3 ++-
clang/lib/StaticAnalyzer/Core/Environment.cpp | 6 ++----
clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 3 ++-
clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp | 6 ++++--
clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp | 2 +-
9 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Taint.h b/clang/include/clang/StaticAnalyzer/Checkers/Taint.h
index 0145973c3b951..9f1b7e946f036 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Taint.h
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Taint.h
@@ -26,7 +26,8 @@ using TaintTagType = unsigned;
static constexpr TaintTagType TaintTagGeneric = 0;
-/// Create a new state in which the value of the expression is marked as tainted.
+/// Create a new state in which the value of the expression is marked as
+/// tainted.
[[nodiscard]] ProgramStateRef addTaint(ProgramStateRef State, const Expr *Ex,
const LocationContext *LCtx,
TaintTagType Kind = TaintTagGeneric);
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index 00cdf1fd33c08..b567ede9855f6 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -168,9 +168,7 @@ class CheckerContext {
}
/// Get the value of arbitrary expressions at this point in the path.
- SVal getSVal(const Expr *Ex) const {
- return Pred->getSVal(Ex);
- }
+ SVal getSVal(const Expr *Ex) const { return Pred->getSVal(Ex); }
ConstCFGElementRef getCFGElementRef() const { return Eng.getCFGElementRef(); }
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
index 2430c3e305a16..10bf33df73b3a 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
@@ -32,8 +32,8 @@ class SymbolReaper;
/// This allows the environment to manage context-sensitive bindings,
/// which is essentially for modeling recursive function analysis, among
/// other things.
-class EnvironmentEntry : public std::pair<const Expr *,
- const StackFrameContext *> {
+class EnvironmentEntry
+ : public std::pair<const Expr *, const StackFrameContext *> {
public:
EnvironmentEntry(const Expr *Ex, const LocationContext *L);
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index f6d1909417c28..936a57921cb03 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -793,7 +793,7 @@ inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) c
}
inline SVal ProgramState::getSVal(const Expr *Ex,
- const LocationContext *LCtx) const{
+ const LocationContext *LCtx) const {
return Env.getSVal(EnvironmentEntry(Ex, LCtx),
*getStateManager().svalBuilder);
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/Taint.cpp b/clang/lib/StaticAnalyzer/Checkers/Taint.cpp
index 0606b7efc0d8e..323e02569b989 100644
--- a/clang/lib/StaticAnalyzer/Checkers/Taint.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/Taint.cpp
@@ -171,7 +171,8 @@ std::vector<SymbolRef> taint::getTaintedSymbols(ProgramStateRef State,
const Expr *Ex,
const LocationContext *LCtx,
TaintTagType Kind) {
- return getTaintedSymbolsImpl(State, Ex, LCtx, Kind, /*ReturnFirstOnly=*/false);
+ return getTaintedSymbolsImpl(State, Ex, LCtx, Kind,
+ /*ReturnFirstOnly=*/false);
}
std::vector<SymbolRef> taint::getTaintedSymbols(ProgramStateRef State, SVal V,
diff --git a/clang/lib/StaticAnalyzer/Core/Environment.cpp b/clang/lib/StaticAnalyzer/Core/Environment.cpp
index 14fa9b1024fdd..df9c6eae51abb 100644
--- a/clang/lib/StaticAnalyzer/Core/Environment.cpp
+++ b/clang/lib/StaticAnalyzer/Core/Environment.cpp
@@ -64,10 +64,8 @@ static const Expr *ignoreTransparentExprs(const Expr *E) {
}
EnvironmentEntry::EnvironmentEntry(const Expr *S, const LocationContext *L)
- : std::pair<const Expr *,
- const StackFrameContext *>(ignoreTransparentExprs(S),
- L ? L->getStackFrame()
- : nullptr) {}
+ : std::pair<const Expr *, const StackFrameContext *>(
+ ignoreTransparentExprs(S), L ? L->getStackFrame() : nullptr) {}
SVal Environment::lookupExpr(const EnvironmentEntry &E) const {
const SVal* X = ExprBindings.lookup(E);
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index a46485f858fac..7fdfdd5d6d415 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -2062,7 +2062,8 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
for (auto Child : Ex->children()) {
assert(Child);
const Expr *ChildExpr = dyn_cast<Expr>(Child);
- SVal Val = ChildExpr ? State->getSVal(ChildExpr, LCtx) : UnknownVal();
+ SVal Val =
+ ChildExpr ? State->getSVal(ChildExpr, LCtx) : UnknownVal();
State = escapeValues(State, Val, PSK_EscapeOther);
}
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 20f836d722827..1fac6588b40d9 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -307,9 +307,11 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
// Ensure that the return type matches the type of the returned Expr.
if (wasDifferentDeclUsedForInlining(Call, CalleeCtx)) {
- QualType ReturnedTy = CallEvent::getDeclaredResultType(CalleeCtx->getDecl());
+ QualType ReturnedTy =
+ CallEvent::getDeclaredResultType(CalleeCtx->getDecl());
if (!ReturnedTy.isNull()) {
- V = adjustReturnValue(V, CE->getType(), ReturnedTy, getStoreManager());
+ V = adjustReturnValue(V, CE->getType(), ReturnedTy,
+ getStoreManager());
}
}
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
index e4914782acb2f..7d9702ce98396 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
@@ -114,7 +114,7 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
const Expr *collection = S->getCollection();
const ConstCFGElementRef &elemRef = getCFGElementRef();
ProgramStateRef state = Pred->getState();
-
+
SVal collectionV = state->getSVal(collection, Pred->getLocationContext());
SVal elementV = UnknownVal();
>From 55b92eac4ddfbb596b8622589f5fe556d46fd8f1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=A1bor=20T=C3=B3thv=C3=A1ri?=
<gabor.tothvari at ericsson.com>
Date: Thu, 23 Apr 2026 11:36:52 +0200
Subject: [PATCH 5/7] Renaming Ex to E, and applying DRY to a few declarations
---
.../clang/StaticAnalyzer/Checkers/Taint.h | 8 ++++----
.../Core/PathSensitive/CallEvent.h | 4 ++--
.../Core/PathSensitive/CheckerContext.h | 2 +-
.../Core/PathSensitive/Environment.h | 2 +-
.../Core/PathSensitive/ExplodedGraph.h | 4 ++--
.../Core/PathSensitive/ProgramState.h | 19 +++++++++----------
.../Checkers/BasicObjCFoundationChecks.cpp | 4 ++--
.../RetainCountChecker/RetainCountChecker.cpp | 2 +-
clang/lib/StaticAnalyzer/Checkers/Taint.cpp | 16 ++++++++--------
.../Core/BugReporterVisitors.cpp | 2 +-
clang/lib/StaticAnalyzer/Core/Environment.cpp | 4 ++--
clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 4 ++--
12 files changed, 35 insertions(+), 36 deletions(-)
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Taint.h b/clang/include/clang/StaticAnalyzer/Checkers/Taint.h
index 9f1b7e946f036..1df3fa277a95d 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Taint.h
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Taint.h
@@ -28,7 +28,7 @@ static constexpr TaintTagType TaintTagGeneric = 0;
/// Create a new state in which the value of the expression is marked as
/// tainted.
-[[nodiscard]] ProgramStateRef addTaint(ProgramStateRef State, const Expr *Ex,
+[[nodiscard]] ProgramStateRef addTaint(ProgramStateRef State, const Expr *E,
const LocationContext *LCtx,
TaintTagType Kind = TaintTagGeneric);
@@ -63,7 +63,7 @@ addPartialTaint(ProgramStateRef State, SymbolRef ParentSym,
TaintTagType Kind = TaintTagGeneric);
/// Check if the expression has a tainted value in the given state.
-bool isTainted(ProgramStateRef State, const Expr *Ex,
+bool isTainted(ProgramStateRef State, const Expr *E,
const LocationContext *LCtx,
TaintTagType Kind = TaintTagGeneric);
@@ -81,7 +81,7 @@ bool isTainted(ProgramStateRef State, const MemRegion *Reg,
TaintTagType Kind = TaintTagGeneric);
/// Returns the tainted Symbols for a given expression and state.
-std::vector<SymbolRef> getTaintedSymbols(ProgramStateRef State, const Expr *Ex,
+std::vector<SymbolRef> getTaintedSymbols(ProgramStateRef State, const Expr *E,
const LocationContext *LCtx,
TaintTagType Kind = TaintTagGeneric);
@@ -100,7 +100,7 @@ std::vector<SymbolRef> getTaintedSymbols(ProgramStateRef State,
TaintTagType Kind = TaintTagGeneric);
std::vector<SymbolRef> getTaintedSymbolsImpl(ProgramStateRef State,
- const Expr *Ex,
+ const Expr *E,
const LocationContext *LCtx,
TaintTagType Kind,
bool returnFirstOnly);
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index a855ef0381056..30fedd91a942c 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -199,8 +199,8 @@ class CallEvent {
virtual void cloneTo(void *Dest) const = 0;
/// Get the value of arbitrary expressions at this point in the path.
- SVal getSVal(const Expr *Ex) const {
- return getState()->getSVal(Ex, getLocationContext());
+ SVal getSVal(const Expr *E) const {
+ return getState()->getSVal(E, getLocationContext());
}
using ValueList = SmallVectorImpl<SVal>;
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index b567ede9855f6..9225fefa36aff 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -168,7 +168,7 @@ class CheckerContext {
}
/// Get the value of arbitrary expressions at this point in the path.
- SVal getSVal(const Expr *Ex) const { return Pred->getSVal(Ex); }
+ SVal getSVal(const Expr *E) const { return Pred->getSVal(E); }
ConstCFGElementRef getCFGElementRef() const { return Eng.getCFGElementRef(); }
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
index 10bf33df73b3a..2e980110c2ff0 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
@@ -35,7 +35,7 @@ class SymbolReaper;
class EnvironmentEntry
: public std::pair<const Expr *, const StackFrameContext *> {
public:
- EnvironmentEntry(const Expr *Ex, const LocationContext *L);
+ EnvironmentEntry(const Expr *E, const LocationContext *L);
const Expr *getExpr() const { return first; }
const LocationContext *getLocationContext() const { return second; }
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index a359f9259c6e4..e86afffd8d5d7 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -169,8 +169,8 @@ class ExplodedNode : public llvm::FoldingSetNode {
}
/// Get the value of an arbitrary expression at this node.
- SVal getSVal(const Expr *Ex) const {
- return getState()->getSVal(Ex, getLocationContext());
+ SVal getSVal(const Expr *E) const {
+ return getState()->getSVal(E, getLocationContext());
}
static void Profile(llvm::FoldingSetNodeID &ID,
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index 936a57921cb03..95d86c722b6a0 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -377,10 +377,10 @@ class ProgramState : public llvm::FoldingSetNode {
/// Get the lvalue for an array index.
SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const;
- /// Returns the SVal bound to the expression \p Ex in the state's environment.
- SVal getSVal(const Expr *Ex, const LocationContext *LCtx) const;
+ /// Returns the SVal bound to the expression \p E in the state's environment.
+ SVal getSVal(const Expr *E, const LocationContext *LCtx) const;
- SVal getSValAsScalarOrLoc(const Expr *Ex, const LocationContext *LCtx) const;
+ SVal getSValAsScalarOrLoc(const Expr *E, const LocationContext *LCtx) const;
/// Return the value bound to the specified location.
/// Returns UnknownVal() if none found.
@@ -792,18 +792,17 @@ inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) c
return UnknownVal();
}
-inline SVal ProgramState::getSVal(const Expr *Ex,
+inline SVal ProgramState::getSVal(const Expr *E,
const LocationContext *LCtx) const {
- return Env.getSVal(EnvironmentEntry(Ex, LCtx),
- *getStateManager().svalBuilder);
+ return Env.getSVal(EnvironmentEntry(E, LCtx), *getStateManager().svalBuilder);
}
inline SVal
-ProgramState::getSValAsScalarOrLoc(const Expr *Ex,
+ProgramState::getSValAsScalarOrLoc(const Expr *E,
const LocationContext *LCtx) const {
- QualType T = Ex->getType();
- if (Ex->isGLValue() || Loc::isLocType(T) || T->isIntegralOrEnumerationType())
- return getSVal(Ex, LCtx);
+ QualType T = E->getType();
+ if (E->isGLValue() || Loc::isLocType(T) || T->isIntegralOrEnumerationType())
+ return getSVal(E, LCtx);
return UnknownVal();
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
index e8c14c4eb803c..cd7a4b0edad8c 100644
--- a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -885,8 +885,8 @@ static ProgramStateRef checkElementNonNil(CheckerContext &C,
const VarDecl *ElemDecl = cast<VarDecl>(DS->getSingleDecl());
assert(ElemDecl->getInit() == nullptr);
ElementLoc = State->getLValue(ElemDecl, LCtx);
- } else if (const auto *Ex = dyn_cast<Expr>(Element)) {
- ElementLoc = State->getSVal(Ex, LCtx).getAs<Loc>();
+ } else if (const auto *E = dyn_cast<Expr>(Element)) {
+ ElementLoc = State->getSVal(E, LCtx).getAs<Loc>();
}
if (!ElementLoc)
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index f4fc5e5da03f5..9f9d64b43a7f7 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -229,7 +229,7 @@ void RetainCountChecker::processObjCLiterals(CheckerContext &C,
ProgramStateRef state = C.getState();
const ExplodedNode *pred = C.getPredecessor();
for (const Stmt *Child : Ex->children()) {
- const Expr *ChildAsExpr = dyn_cast<Expr>(Child);
+ const auto *ChildAsExpr = dyn_cast<Expr>(Child);
SVal V = ChildAsExpr ? pred->getSVal(ChildAsExpr) : UnknownVal();
if (SymbolRef sym = V.getAsSymbol())
if (const RefVal* T = getRefBinding(state, sym)) {
diff --git a/clang/lib/StaticAnalyzer/Checkers/Taint.cpp b/clang/lib/StaticAnalyzer/Checkers/Taint.cpp
index 323e02569b989..f10aecd22d17b 100644
--- a/clang/lib/StaticAnalyzer/Checkers/Taint.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/Taint.cpp
@@ -43,10 +43,10 @@ void taint::dumpTaint(ProgramStateRef State) {
printTaint(State, llvm::errs());
}
-ProgramStateRef taint::addTaint(ProgramStateRef State, const Expr *Ex,
+ProgramStateRef taint::addTaint(ProgramStateRef State, const Expr *E,
const LocationContext *LCtx,
TaintTagType Kind) {
- return addTaint(State, State->getSVal(Ex, LCtx), Kind);
+ return addTaint(State, State->getSVal(E, LCtx), Kind);
}
ProgramStateRef taint::addTaint(ProgramStateRef State, SVal V,
@@ -145,9 +145,9 @@ ProgramStateRef taint::addPartialTaint(ProgramStateRef State,
return NewState;
}
-bool taint::isTainted(ProgramStateRef State, const Expr *Ex,
+bool taint::isTainted(ProgramStateRef State, const Expr *E,
const LocationContext *LCtx, TaintTagType Kind) {
- return !getTaintedSymbolsImpl(State, Ex, LCtx, Kind, /*ReturnFirstOnly=*/true)
+ return !getTaintedSymbolsImpl(State, E, LCtx, Kind, /*ReturnFirstOnly=*/true)
.empty();
}
@@ -168,10 +168,10 @@ bool taint::isTainted(ProgramStateRef State, SymbolRef Sym, TaintTagType Kind) {
}
std::vector<SymbolRef> taint::getTaintedSymbols(ProgramStateRef State,
- const Expr *Ex,
+ const Expr *E,
const LocationContext *LCtx,
TaintTagType Kind) {
- return getTaintedSymbolsImpl(State, Ex, LCtx, Kind,
+ return getTaintedSymbolsImpl(State, E, LCtx, Kind,
/*ReturnFirstOnly=*/false);
}
@@ -193,11 +193,11 @@ std::vector<SymbolRef> taint::getTaintedSymbols(ProgramStateRef State,
}
std::vector<SymbolRef> taint::getTaintedSymbolsImpl(ProgramStateRef State,
- const Expr *Ex,
+ const Expr *E,
const LocationContext *LCtx,
TaintTagType Kind,
bool returnFirstOnly) {
- SVal val = State->getSVal(Ex, LCtx);
+ SVal val = State->getSVal(E, LCtx);
return getTaintedSymbolsImpl(State, val, Kind, returnFirstOnly);
}
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index bcfa2a38bed4f..2942eae367767 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -1740,7 +1740,7 @@ PathDiagnosticPieceRef StoreSiteFinder::VisitNode(const ExplodedNode *Succ,
if (DS) {
SI.StoreKind = StoreInfo::Initialization;
- } else if (const BlockExpr *BExpr = dyn_cast<BlockExpr>(S)) {
+ } else if (const auto *BExpr = dyn_cast<BlockExpr>(S)) {
SI.StoreKind = StoreInfo::BlockCapture;
if (VR) {
// See if we can get the BlockVarRegion.
diff --git a/clang/lib/StaticAnalyzer/Core/Environment.cpp b/clang/lib/StaticAnalyzer/Core/Environment.cpp
index df9c6eae51abb..da0f058ec2ddb 100644
--- a/clang/lib/StaticAnalyzer/Core/Environment.cpp
+++ b/clang/lib/StaticAnalyzer/Core/Environment.cpp
@@ -63,9 +63,9 @@ static const Expr *ignoreTransparentExprs(const Expr *E) {
return ignoreTransparentExprs(E);
}
-EnvironmentEntry::EnvironmentEntry(const Expr *S, const LocationContext *L)
+EnvironmentEntry::EnvironmentEntry(const Expr *E, const LocationContext *L)
: std::pair<const Expr *, const StackFrameContext *>(
- ignoreTransparentExprs(S), L ? L->getStackFrame() : nullptr) {}
+ ignoreTransparentExprs(E), L ? L->getStackFrame() : nullptr) {}
SVal Environment::lookupExpr(const EnvironmentEntry &E) const {
const SVal* X = ExprBindings.lookup(E);
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 7fdfdd5d6d415..7cfb3bb907f7a 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -2061,7 +2061,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
->getType()->isRecordType()))
for (auto Child : Ex->children()) {
assert(Child);
- const Expr *ChildExpr = dyn_cast<Expr>(Child);
+ const auto *ChildExpr = dyn_cast<Expr>(Child);
SVal Val =
ChildExpr ? State->getSVal(ChildExpr, LCtx) : UnknownVal();
State = escapeValues(State, Val, PSK_EscapeOther);
@@ -2798,7 +2798,7 @@ assumeCondition(const Stmt *ConditionStmt, ExplodedNode *N) {
return std::pair<ProgramStateRef, ProgramStateRef>{nullptr, State};
}
- const Expr *ConditionExpr = dyn_cast<Expr>(ConditionStmt);
+ const auto *ConditionExpr = dyn_cast<Expr>(ConditionStmt);
assert(ConditionExpr && "The condition must be an Expr from here!");
SVal X = State->getSVal(ConditionExpr, N->getLocationContext());
>From fdfd6dd470347c66019283ffea20713a056b5161 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=A1bor=20T=C3=B3thv=C3=A1ri?=
<gabor.tothvari at ericsson.com>
Date: Sat, 25 Apr 2026 19:51:57 +0200
Subject: [PATCH 6/7] Remove outdated FIXME comment and unnecessary early
return.
---
clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp | 3 ---
clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp | 5 +----
2 files changed, 1 insertion(+), 7 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
index 255624968fffc..6e2abb4664a4e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
@@ -66,9 +66,6 @@ void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
return;
const Expr *Ex = dyn_cast<Expr>(Condition);
- if (!Ex)
- return;
-
if (!Ctx.getSVal(Ex).isUndef())
return;
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 1fac6588b40d9..d3a0c20fd8671 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -297,10 +297,7 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
if (CE) {
if (const ReturnStmt *RS = dyn_cast_or_null<ReturnStmt>(LastSt)) {
const LocationContext *LCtx = CEBNode->getLocationContext();
- // FIXME: This tries to look up the return statement in the environment,
- // which is special cased to look up the subexpression RS->getRetValue()
- // in environment. Instead of relying on this hack, pass
- // RS->getRetValue() to getSVal() after checking it for nullness.
+
SVal V = UndefinedVal();
if (RS->getRetValue())
V = State->getSVal(RS->getRetValue(), LCtx);
>From fd246d803610304c7ffa9b0675b25b7fce17f6d5 Mon Sep 17 00:00:00 2001
From: tigbr <tigbrcode at protonmail.com>
Date: Sat, 25 Apr 2026 18:56:19 +0000
Subject: [PATCH 7/7] Apply DRY to declaration and change dyn_cast to cast
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Balázs Benics <benicsbalazs at gmail.com>
---
clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
index 6e2abb4664a4e..3e8377c3ae189 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
@@ -65,7 +65,7 @@ void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
if (isa<ObjCForCollectionStmt>(Condition))
return;
- const Expr *Ex = dyn_cast<Expr>(Condition);
+ const auto *Ex = cast<Expr>(Condition);
if (!Ctx.getSVal(Ex).isUndef())
return;
More information about the cfe-commits
mailing list