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 | a7bcbde814070b71306dfbee42841d8fe3699e66 (patch) | |
tree | 7f28395c80c082e491ed85a717ad4d15a5fa1ecb /clang/lib/Analysis/GRExprEngine.cpp | |
parent | 857f41c6505f168c9cd08d3f5e1c07d3eb0ae441 (diff) | |
download | bcm5719-llvm-a7bcbde814070b71306dfbee42841d8fe3699e66.tar.gz bcm5719-llvm-a7bcbde814070b71306dfbee42841d8fe3699e66.zip |
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.
llvm-svn: 91987
Diffstat (limited to 'clang/lib/Analysis/GRExprEngine.cpp')
-rw-r--r-- | clang/lib/Analysis/GRExprEngine.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp index 22becee2892..ceefea81f5c 100644 --- a/clang/lib/Analysis/GRExprEngine.cpp +++ b/clang/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. |