Fix CFG assertion failure reported in PR 9467. This was due to recent changes in optimizing CFGs for switch statements.

llvm-svn: 127563
This commit is contained in:
Ted Kremenek 2011-03-13 03:48:04 +00:00
parent ac824ee462
commit 53e6538fa8
2 changed files with 25 additions and 9 deletions

View File

@ -2233,8 +2233,9 @@ CFGBlock* CFGBuilder::VisitSwitchStmt(SwitchStmt* Terminator) {
// Determine if the switch condition can be explicitly evaluated.
assert(Terminator->getCond() && "switch condition must be non-NULL");
Expr::EvalResult result;
tryEvaluate(Terminator->getCond(), result);
SaveAndRestore<Expr::EvalResult*> save_switchCond(switchCond, &result);
bool b = tryEvaluate(Terminator->getCond(), result);
SaveAndRestore<Expr::EvalResult*> save_switchCond(switchCond,
b ? &result : 0);
// If body is not a compound statement create implicit scope
// and add destructors.
@ -2271,18 +2272,21 @@ CFGBlock* CFGBuilder::VisitSwitchStmt(SwitchStmt* Terminator) {
}
static bool shouldAddCase(bool &switchExclusivelyCovered,
const Expr::EvalResult &switchCond,
const Expr::EvalResult *switchCond,
const CaseStmt *CS,
ASTContext &Ctx) {
if (!switchCond)
return true;
bool addCase = false;
if (!switchExclusivelyCovered) {
if (switchCond.Val.isInt()) {
if (switchCond->Val.isInt()) {
// Evaluate the LHS of the case value.
Expr::EvalResult V1;
CS->getLHS()->Evaluate(V1, Ctx);
assert(V1.Val.isInt());
const llvm::APSInt &condInt = switchCond.Val.getInt();
const llvm::APSInt &condInt = switchCond->Val.getInt();
const llvm::APSInt &lhsInt = V1.Val.getInt();
if (condInt == lhsInt) {
@ -2312,7 +2316,6 @@ CFGBlock* CFGBuilder::VisitCaseStmt(CaseStmt* CS) {
// CaseStmts are essentially labels, so they are the first statement in a
// block.
CFGBlock *TopBlock = 0, *LastBlock = 0;
assert(switchCond);
if (Stmt *Sub = CS->getSubStmt()) {
// For deeply nested chains of CaseStmts, instead of doing a recursion
@ -2328,7 +2331,7 @@ CFGBlock* CFGBuilder::VisitCaseStmt(CaseStmt* CS) {
TopBlock = currentBlock;
addSuccessor(SwitchTerminatedBlock,
shouldAddCase(switchExclusivelyCovered, *switchCond,
shouldAddCase(switchExclusivelyCovered, switchCond,
CS, *Context)
? currentBlock : 0);
@ -2355,7 +2358,7 @@ CFGBlock* CFGBuilder::VisitCaseStmt(CaseStmt* CS) {
// statement.
assert(SwitchTerminatedBlock);
addSuccessor(SwitchTerminatedBlock,
shouldAddCase(switchExclusivelyCovered, *switchCond,
shouldAddCase(switchExclusivelyCovered, switchCond,
CS, *Context)
? CaseBlock : 0);

View File

@ -1287,4 +1287,17 @@ void test_switch() {
break;
}
}
}
}
// PR 9467. Tests various CFG optimizations. This previously crashed.
static void test(unsigned int bit_mask)
{
unsigned int bit_index;
for (bit_index = 0;
bit_index < 24;
bit_index++) {
switch ((0x01 << bit_index) & bit_mask) {
case 0x100000: ;
}
}
}