diff options
Diffstat (limited to 'lib/Analysis/GRExprEngine.cpp')
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 22becee289..ceefea81f5 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -661,6 +661,12 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) { VisitCast(C, C->getSubExpr(), Pred, Dst, false); break; } + + case Stmt::IfStmtClass: + // This case isn't for branch processing, but for handling the + // initialization of a condition variable. + VisitIfStmtCondInit(cast<IfStmt>(S), Pred, Dst); + break; case Stmt::InitListExprClass: VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst); @@ -749,6 +755,7 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred, Ex->getLocStart(), "Error evaluating statement"); + Ex = Ex->IgnoreParens(); if (Ex != CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(Ex)){ @@ -2223,6 +2230,36 @@ void GRExprEngine::VisitDeclStmt(DeclStmt *DS, ExplodedNode *Pred, } } +void GRExprEngine::VisitIfStmtCondInit(IfStmt *IS, ExplodedNode *Pred, + ExplodedNodeSet& Dst) { + + VarDecl* VD = IS->getConditionVariable(); + Expr* InitEx = VD->getInit(); + + ExplodedNodeSet Tmp; + Visit(InitEx, Pred, Tmp); + + for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { + ExplodedNode *N = *I; + const GRState *state = GetState(N); + + const LocationContext *LC = N->getLocationContext(); + SVal InitVal = state->getSVal(InitEx); + QualType T = VD->getType(); + + // Recover some path-sensitivity if a scalar value evaluated to + // UnknownVal. + if (InitVal.isUnknown() || + !getConstraintManager().canReasonAbout(InitVal)) { + InitVal = ValMgr.getConjuredSymbolVal(NULL, InitEx, + Builder->getCurrentBlockCount()); + } + + EvalBind(Dst, IS, IS, N, state, + loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true); + } +} + namespace { // This class is used by VisitInitListExpr as an item in a worklist // for processing the values contained in an InitListExpr. |