[clang] [analyzer] Add BranchCondition callback to 'switch' (PR #182058)
DonĂ¡t Nagy via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 19 02:52:05 PST 2026
================
@@ -3106,70 +3108,83 @@ void ExprEngine::processEndOfFunction(NodeBuilderContext& BC,
/// nodes by processing the 'effects' of a switch statement.
void ExprEngine::processSwitch(NodeBuilderContext &BC, const SwitchStmt *Switch,
ExplodedNode *Pred, ExplodedNodeSet &Dst) {
+ currBldrCtx = &BC;
const Expr *Condition = Switch->getCond();
SwitchNodeBuilder Builder(Dst, BC);
+ ExplodedNodeSet CheckersOutSet;
- ProgramStateRef State = Pred->getState();
- SVal CondV = State->getSVal(Condition, Pred->getLocationContext());
-
- if (CondV.isUndef()) {
- // FIXME: Emit warnings when the switch condition is undefined.
- return;
- }
+ getCheckerManager().runCheckersForBranchCondition(
+ Condition->IgnoreParens(), CheckersOutSet, Pred, *this);
- std::optional<NonLoc> CondNL = CondV.getAs<NonLoc>();
+ for (ExplodedNode *Node : CheckersOutSet) {
+ ProgramStateRef State = Node->getState();
- for (const CFGBlock *Block : Builder) {
- // Successor may be pruned out during CFG construction.
- if (!Block)
+ SVal CondV = State->getSVal(Condition, Node->getLocationContext());
+ if (CondV.isUndef()) {
+ // This can only happen if core.uninitialized.Branch is disabled.
continue;
+ }
- const CaseStmt *Case = cast<CaseStmt>(Block->getLabel());
+ std::optional<NonLoc> CondNL = CondV.getAs<NonLoc>();
----------------
NagyDonat wrote:
In my mind it is grouped together with the preceding statements (`CondV = State->getSVal(...)` etc.) and I placed this "inspect the value of the condition" block here because it depends on the `Node` (the loop variable of the outer `for` loop) but doesn't depend on the `Block` (the loop variable of the inner loop).
https://github.com/llvm/llvm-project/pull/182058
More information about the cfe-commits
mailing list