[cfe-commits] r91987 - in /cfe/trunk: include/clang/Analysis/PathSensitive/GRExprEngine.h lib/Analysis/CFG.cpp lib/Analysis/GRExprEngine.cpp test/Analysis/misc-ps-region-store.cpp
Ted Kremenek
kremenek at apple.com
Tue Dec 22 20:49:04 PST 2009
Author: kremenek
Date: Tue Dec 22 22:49:01 2009
New Revision: 91987
URL: http://llvm.org/viewvc/llvm-project?rev=91987&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
cfe/trunk/lib/Analysis/CFG.cpp
cfe/trunk/lib/Analysis/GRExprEngine.cpp
cfe/trunk/test/Analysis/misc-ps-region-store.cpp
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=91987&r1=91986&r2=91987&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Tue Dec 22 22:49:01 2009
@@ -293,6 +293,11 @@
void VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R, ExplodedNode* Pred,
ExplodedNodeSet& Dst);
+ /// VisitIfStmtCondInit - Transfer function for handling the initialization
+ /// of a condition variable in an IfStmt.
+ void VisitIfStmtCondInit(IfStmt *IS, ExplodedNode *Pred,
+ ExplodedNodeSet& Dst);
+
void VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
ExplodedNodeSet& Dst);
Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=91987&r1=91986&r2=91987&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Tue Dec 22 22:49:01 2009
@@ -776,7 +776,19 @@
// Add the condition as the last statement in the new block. This may create
// new blocks as the condition may contain control-flow. Any newly created
// blocks will be pointed to be "Block".
- return addStmt(I->getCond());
+ Block = addStmt(I->getCond());
+
+ // Finally, if the IfStmt contains a condition variable, add both the IfStmt
+ // and the condition variable initialization to the CFG.
+ if (VarDecl *VD = I->getConditionVariable()) {
+ if (Expr *Init = VD->getInit()) {
+ autoCreateBlock();
+ AppendStmt(Block, I, AddStmtChoice::AlwaysAdd);
+ addStmt(Init);
+ }
+ }
+
+ return Block;
}
Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=91987&r1=91986&r2=91987&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Tue Dec 22 22:49:01 2009
@@ -661,6 +661,12 @@
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 @@
Ex->getLocStart(),
"Error evaluating statement");
+
Ex = Ex->IgnoreParens();
if (Ex != CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(Ex)){
@@ -2223,6 +2230,36 @@
}
}
+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.
Modified: cfe/trunk/test/Analysis/misc-ps-region-store.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps-region-store.cpp?rev=91987&r1=91986&r2=91987&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/misc-ps-region-store.cpp (original)
+++ cfe/trunk/test/Analysis/misc-ps-region-store.cpp Tue Dec 22 22:49:01 2009
@@ -34,3 +34,10 @@
return test3_aux(x);
}
+int test_init_in_condition_aux();
+int test_init_in_condition() {
+ if (int x = test_init_in_condition_aux()) { // no-warning
+ return 1;
+ }
+ return 0;
+}
More information about the cfe-commits
mailing list