@@ -2872,9 +2872,6 @@ void ExprEngine::processBranch(
28722872
28732873 BranchNodeBuilder Builder (Dst, BldCtx, DstT, DstF);
28742874 for (ExplodedNode *PredN : CheckersOutSet) {
2875- if (PredN->isSink ())
2876- continue ;
2877-
28782875 ProgramStateRef PrevState = PredN->getState ();
28792876
28802877 ProgramStateRef StTrue = PrevState, StFalse = PrevState;
@@ -3106,70 +3103,83 @@ void ExprEngine::processEndOfFunction(NodeBuilderContext& BC,
31063103// / nodes by processing the 'effects' of a switch statement.
31073104void ExprEngine::processSwitch (NodeBuilderContext &BC, const SwitchStmt *Switch,
31083105 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
3106+ currBldrCtx = &BC;
31093107 const Expr *Condition = Switch->getCond ();
31103108
31113109 SwitchNodeBuilder Builder (Dst, BC);
3110+ ExplodedNodeSet CheckersOutSet;
31123111
3113- ProgramStateRef State = Pred->getState ();
3114- SVal CondV = State->getSVal (Condition, Pred->getLocationContext ());
3115-
3116- if (CondV.isUndef ()) {
3117- // FIXME: Emit warnings when the switch condition is undefined.
3118- return ;
3119- }
3112+ getCheckerManager ().runCheckersForBranchCondition (
3113+ Condition->IgnoreParens (), CheckersOutSet, Pred, *this );
31203114
3121- std::optional<NonLoc> CondNL = CondV.getAs <NonLoc>();
3115+ for (ExplodedNode *Node : CheckersOutSet) {
3116+ ProgramStateRef State = Node->getState ();
31223117
3123- for ( const CFGBlock *Block : Builder) {
3124- // Successor may be pruned out during CFG construction.
3125- if (!Block)
3118+ SVal CondV = State-> getSVal (Condition, Node-> getLocationContext ());
3119+ if (CondV. isUndef ()) {
3120+ // This can only happen if core.uninitialized.Branch is disabled.
31263121 continue ;
3122+ }
31273123
3128- const CaseStmt *Case = cast<CaseStmt>(Block-> getLabel () );
3124+ std::optional<NonLoc> CondNL = CondV. getAs <NonLoc>( );
31293125
3130- // Evaluate the LHS of the case value.
3131- llvm::APSInt V1 = Case->getLHS ()->EvaluateKnownConstInt (getContext ());
3132- assert (V1.getBitWidth () == getContext ().getIntWidth (Condition->getType ()));
3126+ for (const CFGBlock *Block : Builder) {
3127+ // Successor may be pruned out during CFG construction.
3128+ if (!Block)
3129+ continue ;
31333130
3134- // Get the RHS of the case, if it exists.
3135- llvm::APSInt V2;
3136- if (const Expr *E = Case->getRHS ())
3137- V2 = E->EvaluateKnownConstInt (getContext ());
3138- else
3139- V2 = V1;
3131+ const CaseStmt *Case = cast<CaseStmt>(Block->getLabel ());
31403132
3141- ProgramStateRef StateMatching;
3142- if (CondNL) {
3143- // Split the state: this "case:" matches / does not match.
3144- std::tie (StateMatching, State) =
3145- State->assumeInclusiveRange (*CondNL, V1, V2);
3146- } else {
3147- // The switch condition is UnknownVal, so we enter each "case:" without
3148- // any state update.
3149- StateMatching = State;
3150- }
3133+ // Evaluate the LHS of the case value.
3134+ llvm::APSInt V1 = Case->getLHS ()->EvaluateKnownConstInt (getContext ());
3135+ assert (V1.getBitWidth () ==
3136+ getContext ().getIntWidth (Condition->getType ()));
31513137
3152- if (StateMatching)
3153- Builder.generateCaseStmtNode (Block, StateMatching, Pred);
3138+ // Get the RHS of the case, if it exists.
3139+ llvm::APSInt V2;
3140+ if (const Expr *E = Case->getRHS ())
3141+ V2 = E->EvaluateKnownConstInt (getContext ());
3142+ else
3143+ V2 = V1;
31543144
3155- // If _not_ entering the current case is infeasible, we are done with
3156- // processing this branch.
3145+ ProgramStateRef StateMatching;
3146+ if (CondNL) {
3147+ // Split the state: this "case:" matches / does not match.
3148+ std::tie (StateMatching, State) =
3149+ State->assumeInclusiveRange (*CondNL, V1, V2);
3150+ } else {
3151+ // The switch condition is UnknownVal, so we enter each "case:" without
3152+ // any state update.
3153+ StateMatching = State;
3154+ }
3155+
3156+ if (StateMatching)
3157+ Builder.generateCaseStmtNode (Block, StateMatching, Node);
3158+
3159+ // If _not_ entering the current case is infeasible, then we are done
3160+ // with processing the paths through the current Node.
3161+ if (!State)
3162+ break ;
3163+ }
31573164 if (!State)
3158- return ;
3159- }
3160- // If we have switch(enum value), the default branch is not
3161- // feasible if all of the enum constants not covered by 'case:' statements
3162- // are not feasible values for the switch condition.
3163- //
3164- // Note that this isn't as accurate as it could be. Even if there isn't
3165- // a case for a particular enum value as long as that enum value isn't
3166- // feasible then it shouldn't be considered for making 'default:' reachable.
3167- if (Condition->IgnoreParenImpCasts ()->getType ()->isEnumeralType ()) {
3168- if (Switch->isAllEnumCasesCovered ())
3169- return ;
3165+ continue ;
3166+
3167+ // If we have switch(enum value), the default branch is not
3168+ // feasible if all of the enum constants not covered by 'case:' statements
3169+ // are not feasible values for the switch condition.
3170+ //
3171+ // Note that this isn't as accurate as it could be. Even if there isn't
3172+ // a case for a particular enum value as long as that enum value isn't
3173+ // feasible then it shouldn't be considered for making 'default:' reachable.
3174+ if (Condition->IgnoreParenImpCasts ()->getType ()->isEnumeralType ()) {
3175+ if (Switch->isAllEnumCasesCovered ())
3176+ continue ;
3177+ }
3178+
3179+ Builder.generateDefaultCaseNode (State, Node);
31703180 }
31713181
3172- Builder. generateDefaultCaseNode (State, Pred) ;
3182+ currBldrCtx = nullptr ;
31733183}
31743184
31753185// ===----------------------------------------------------------------------===//
0 commit comments