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