Enhance dataflow analyses to recognize branch statements in the CFG used as hooks for the initialization of condition variables.

llvm-svn: 92119
This commit is contained in:
Ted Kremenek 2009-12-24 02:40:30 +00:00
parent bb2f57dd39
commit 9c951ab4f1
3 changed files with 44 additions and 1 deletions

View File

@ -25,6 +25,25 @@ public:
void VisitStmt(Stmt* S) {
static_cast< ImplClass* >(this)->VisitChildren(S);
}
void VisitConditionVariableInit(Stmt *S) {
assert(S == this->getCurrentBlkStmt());
VarDecl *CondVar = 0;
switch (S->getStmtClass()) {
#define CONDVAR_CASE(CLASS) \
case Stmt::CLASS ## Class:\
CondVar = cast<CLASS>(S)->getConditionVariable();\
break;
CONDVAR_CASE(IfStmt)
CONDVAR_CASE(ForStmt)
CONDVAR_CASE(SwitchStmt)
CONDVAR_CASE(WhileStmt)
#undef CONDVAR_CASE
default:
assert(false && "Infeasible");
}
static_cast<ImplClass*>(this)->Visit(CondVar->getInit());
}
// Defining operator() allows the visitor to be used as a C++ style functor.
void operator()(Stmt* S) { static_cast<ImplClass*>(this)->BlockStmt_Visit(S);}

View File

@ -54,6 +54,13 @@ public:
else
return RetTy();
}
/// VisitConditionVariableInit - Handle the initialization of condition
/// variables at branches. Valid statements include IfStmt, ForStmt,
/// WhileStmt, and SwitchStmt.
RetTy VisitConditionVariableInit(Stmt *S) {
return RetTy();
}
/// BlockVisit_XXX - Visitor methods for visiting the "root" statements in
/// CFGBlocks. Root statements are the statements that appear explicitly in
@ -65,6 +72,11 @@ public:
NullifyStmt cleanup(CurrentBlkStmt);
switch (S->getStmtClass()) {
case Stmt::IfStmtClass:
case Stmt::ForStmtClass:
case Stmt::WhileStmtClass:
case Stmt::SwitchStmtClass:
return static_cast<ImplClass*>(this)->VisitConditionVariableInit(S);
DISPATCH_CASE(StmtExpr)
DISPATCH_CASE(ConditionalOperator)

View File

@ -112,6 +112,11 @@ public:
void VisitUnaryOperator(UnaryOperator* U);
void Visit(Stmt *S);
void VisitTerminator(CFGBlock* B);
/// VisitConditionVariableInit - Handle the initialization of condition
/// variables at branches. Valid statements include IfStmt, ForStmt,
/// WhileStmt, and SwitchStmt.
void VisitConditionVariableInit(Stmt *S);
void SetTopValue(LiveVariables::ValTy& V) {
V = AD.AlwaysLive;
@ -126,7 +131,9 @@ void TransferFuncs::Visit(Stmt *S) {
if (AD.Observer)
AD.Observer->ObserveStmt(S,AD,LiveState);
if (getCFG().isBlkExpr(S)) LiveState(S,AD) = Dead;
if (getCFG().isBlkExpr(S))
LiveState(S, AD) = Dead;
StmtVisitor<TransferFuncs,void>::Visit(S);
}
else if (!getCFG().isBlkExpr(S)) {
@ -142,6 +149,11 @@ void TransferFuncs::Visit(Stmt *S) {
LiveState(S,AD) = Alive;
}
}
void TransferFuncs::VisitConditionVariableInit(Stmt *S) {
assert(!getCFG().isBlkExpr(S));
CFGRecStmtVisitor<TransferFuncs>::VisitConditionVariableInit(S);
}
void TransferFuncs::VisitTerminator(CFGBlock* B) {