diff options
author | Bill Wendling <isanbard@gmail.com> | 2011-03-14 20:22:59 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2011-03-14 20:22:59 +0000 |
commit | 67c415d679e705afb12e89a5409ccfc631c00e53 (patch) | |
tree | e87e90edde4833fef5d3896462a2e4af5b5274cb | |
parent | deab766b162f3f95fcb10a78ca94bac660c821fd (diff) | |
download | llvm-67c415d679e705afb12e89a5409ccfc631c00e53.tar.gz |
--- Merging r127563 into '.':
U test/Analysis/misc-ps.m
U lib/Analysis/CFG.cpp
llvm-svn: 127613
-rw-r--r-- | clang/lib/Analysis/CFG.cpp | 19 | ||||
-rw-r--r-- | clang/test/Analysis/misc-ps.m | 15 |
2 files changed, 25 insertions, 9 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index fa98f94057e9..a8c002fe6eb1 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -2201,8 +2201,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. @@ -2239,18 +2240,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) { @@ -2280,7 +2284,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 @@ -2296,7 +2299,7 @@ CFGBlock* CFGBuilder::VisitCaseStmt(CaseStmt* CS) { TopBlock = currentBlock; addSuccessor(SwitchTerminatedBlock, - shouldAddCase(switchExclusivelyCovered, *switchCond, + shouldAddCase(switchExclusivelyCovered, switchCond, CS, *Context) ? currentBlock : 0); @@ -2323,7 +2326,7 @@ CFGBlock* CFGBuilder::VisitCaseStmt(CaseStmt* CS) { // statement. assert(SwitchTerminatedBlock); addSuccessor(SwitchTerminatedBlock, - shouldAddCase(switchExclusivelyCovered, *switchCond, + shouldAddCase(switchExclusivelyCovered, switchCond, CS, *Context) ? CaseBlock : 0); diff --git a/clang/test/Analysis/misc-ps.m b/clang/test/Analysis/misc-ps.m index 8e7092bc15e2..5fa6979d2f9a 100644 --- a/clang/test/Analysis/misc-ps.m +++ b/clang/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: ; + } + } +} |