summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/GRExprEngine.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-12-23 04:49:01 +0000
committerTed Kremenek <kremenek@apple.com>2009-12-23 04:49:01 +0000
commita7bcbde814070b71306dfbee42841d8fe3699e66 (patch)
tree7f28395c80c082e491ed85a717ad4d15a5fa1ecb /clang/lib/Analysis/GRExprEngine.cpp
parent857f41c6505f168c9cd08d3f5e1c07d3eb0ae441 (diff)
downloadbcm5719-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.cpp37
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.
OpenPOWER on IntegriCloud