From e9cd9c0016f103fd45d41d136d5d1084aa42eb75 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Sun, 13 Mar 2011 03:48:04 +0000 Subject: [PATCH] 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 --- lib/Analysis/CFG.cpp | 19 +++++++++++-------- 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 save_switchCond(switchCond, &result); + bool b = tryEvaluate(Terminator->getCond(), result); + SaveAndRestore 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: ; + } + } +} -- 2.40.0