diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-12-23 04:49:01 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-12-23 04:49:01 +0000 |
commit | 61dfbecd8e6181b2ba42ffb5feede27a2bab3b8a (patch) | |
tree | a83619142539ddc193d8c11d617283007b618abc /lib/Analysis/GRExprEngine.cpp | |
parent | 604d939ac15d1398761df313679673d30bb10f27 (diff) |
Add CFG support for the condition variable that can appear in IfStmts in C++ mode.
Add transfer function support in GRExprEngine for IfStmts with initialized condition variables.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91987 91177308-0d34-0410-b5e6-96231b3b80d8
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. |