[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