Right. Thanks for the reminder Doug! On Dec 22, 2009, at 11:32 PM, Douglas Gregor wrote:
> While, switch, and for statements also have condition variables. > > Sent from my iPhone > > On Dec 22, 2009, at 8:49 PM, Ted Kremenek <[email protected]> wrote: > >> 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; >> +} >> >> >> _______________________________________________ >> cfe-commits mailing list >> [email protected] >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
