diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-03-13 03:48:04 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-03-13 03:48:04 +0000 |
commit | e9cd9c0016f103fd45d41d136d5d1084aa42eb75 (patch) | |
tree | 8bda3aecab20f79f14022c1e9451dd5845eb2ae2 | |
parent | 603ea78728e57815fe859665b648837c5cff6c37 (diff) |
Fix CFG assertion failure reported in PR 9467. This was due to recent changes in optimizing CFGs for switch statements.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127563 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Analysis/CFG.cpp | 19 | ||||
-rw-r--r-- | test/Analysis/misc-ps.m | 15 |
2 files changed, 25 insertions, 9 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 8d27c0cc49..8f8c475d35 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -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); diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m index 40270f8c34..b6cbc2553c 100644 --- a/test/Analysis/misc-ps.m +++ b/test/Analysis/misc-ps.m @@ -1287,4 +1287,17 @@ void test_switch() { break; } } -}
\ No newline at end of file +} + +// 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: ; + } + } +} |