]> granicus.if.org Git - clang/commitdiff
Fix CFG assertion failure reported in PR 9467. This was due to recent changes in...
authorTed Kremenek <kremenek@apple.com>
Sun, 13 Mar 2011 03:48:04 +0000 (03:48 +0000)
committerTed Kremenek <kremenek@apple.com>
Sun, 13 Mar 2011 03:48:04 +0000 (03:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127563 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/CFG.cpp
test/Analysis/misc-ps.m

index 8d27c0cc49f189d370439eb9945eac48d11e493b..8f8c475d354d07d3852f1739be32d9097b898ec1 100644 (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);
 
index 40270f8c34fcdb9e0510299dee91d72db477a251..b6cbc2553c18a118d63d8017269a6c0179f06bc4 100644 (file)
@@ -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: ;
+    }
+  }
+}