Teach GRExprEngine to handle the initialization of the condition variable of a SwitchStmt.

llvm-svn: 92102
This commit is contained in:
Ted Kremenek 2009-12-24 00:40:03 +00:00
parent 8b5dc12e52
commit 589493227b
3 changed files with 33 additions and 11 deletions

View File

@ -293,10 +293,10 @@ protected:
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);
/// VisitCondInit - Transfer function for handling the initialization
/// of a condition variable in an IfStmt, SwitchStmt, etc.
void VisitCondInit(VarDecl *VD, Stmt *S, ExplodedNode *Pred,
ExplodedNodeSet& Dst);
void VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
ExplodedNodeSet& Dst);

View File

@ -665,7 +665,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
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);
VisitCondInit(cast<IfStmt>(S)->getConditionVariable(), S, Pred, Dst);
break;
case Stmt::InitListExprClass:
@ -733,6 +733,12 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
case Stmt::StringLiteralClass:
VisitLValue(cast<StringLiteral>(S), Pred, Dst);
break;
case Stmt::SwitchStmtClass:
// This case isn't for branch processing, but for handling the
// initialization of a condition variable.
VisitCondInit(cast<SwitchStmt>(S)->getConditionVariable(), S, Pred, Dst);
break;
case Stmt::UnaryOperatorClass: {
UnaryOperator *U = cast<UnaryOperator>(S);
@ -2230,12 +2236,10 @@ void GRExprEngine::VisitDeclStmt(DeclStmt *DS, ExplodedNode *Pred,
}
}
void GRExprEngine::VisitIfStmtCondInit(IfStmt *IS, ExplodedNode *Pred,
ExplodedNodeSet& Dst) {
VarDecl* VD = IS->getConditionVariable();
Expr* InitEx = VD->getInit();
void GRExprEngine::VisitCondInit(VarDecl *VD, Stmt *S,
ExplodedNode *Pred, ExplodedNodeSet& Dst) {
Expr* InitEx = VD->getInit();
ExplodedNodeSet Tmp;
Visit(InitEx, Pred, Tmp);
@ -2255,7 +2259,7 @@ void GRExprEngine::VisitIfStmtCondInit(IfStmt *IS, ExplodedNode *Pred,
Builder->getCurrentBlockCount());
}
EvalBind(Dst, IS, IS, N, state,
EvalBind(Dst, S, S, N, state,
loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true);
}
}

View File

@ -41,3 +41,21 @@ int test_init_in_condition() {
}
return 0;
}
int test_init_in_condition_switch() {
switch (int x = test_init_in_condition_aux()) { // no-warning
case 1:
return 0;
case 2:
if (x == 2)
return 0;
else {
// Unreachable.
int *p = 0;
*p = 0xDEADBEEF; // no-warning
}
default:
break;
}
return 0;
}