diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 180a01289b12..c28513324b49 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -2742,8 +2742,8 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) { SwitchAlwaysHasSuccessor |= switchExclusivelyCovered; SwitchAlwaysHasSuccessor |= Terminator->isAllEnumCasesCovered() && Terminator->getSwitchCaseList(); - addSuccessor(SwitchTerminatedBlock, - SwitchAlwaysHasSuccessor ? 0 : DefaultCaseBlock); + addSuccessor(SwitchTerminatedBlock, DefaultCaseBlock, + !SwitchAlwaysHasSuccessor); // Add the terminator and condition in the switch block. SwitchTerminatedBlock->setTerminator(Terminator); @@ -2844,10 +2844,9 @@ CFGBlock *CFGBuilder::VisitCaseStmt(CaseStmt *CS) { // Add this block to the list of successors for the block with the switch // statement. assert(SwitchTerminatedBlock); - addSuccessor(SwitchTerminatedBlock, + addSuccessor(SwitchTerminatedBlock, CaseBlock, shouldAddCase(switchExclusivelyCovered, switchCond, - CS, *Context) - ? CaseBlock : 0); + CS, *Context)); // We set Block to NULL to allow lazy creation of a new block (if necessary) Block = NULL; @@ -4034,12 +4033,24 @@ static void print_block(raw_ostream &OS, const CFG* cfg, if (i % 10 == 8) OS << "\n "; - if (*I) - OS << " B" << (*I)->getBlockID(); - else - OS << " NULL"; + CFGBlock *B = *I; + + bool Reachable = true; + if (!B) { + Reachable = false; + B = I->getPossiblyUnreachableBlock(); + } + + if (B) { + OS << " B" << B->getBlockID(); + if (!Reachable) + OS << "(Unreachable)"; + } + else { + OS << " NULL"; + } } - + if (ShowColors) OS.resetColor(); OS << '\n'; diff --git a/clang/test/Analysis/cfg.cpp b/clang/test/Analysis/cfg.cpp index c465acb356b7..1f3bfac2c380 100644 --- a/clang/test/Analysis/cfg.cpp +++ b/clang/test/Analysis/cfg.cpp @@ -199,7 +199,7 @@ namespace NoReturnSingleSuccessor { // CHECK-NEXT: 1: x // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, int) // CHECK-NEXT: 3: return [B1.2]; -// CHECK-NEXT: Preds (4): B3 B4 B5 B6 +// CHECK-NEXT: Preds (5): B3 B4 B5 B6 B2(Unreachable) // CHECK-NEXT: Succs (1): B0 // CHECK: [B2] // CHECK-NEXT: 1: 0 @@ -209,7 +209,7 @@ namespace NoReturnSingleSuccessor { // CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, IntegralCast, int) // CHECK-NEXT: T: switch [B2.5] // CHECK-NEXT: Preds (1): B7 -// CHECK-NEXT: Succs (5): B3 B4 B5 B6 NULL +// CHECK-NEXT: Succs (5): B3 B4 B5 B6 B1(Unreachable) // CHECK: [B3] // CHECK-NEXT: case D: // CHECK-NEXT: 1: 4 @@ -275,13 +275,14 @@ int test_enum_with_extension(enum MyEnum value) { // CHECK-NEXT: 5: [B2.4] (ImplicitCastExpr, IntegralCast, int) // CHECK-NEXT: T: switch [B2.5] // CHECK-NEXT: Preds (1): B7 -// CHECK-NEXT: Succs (4): B4 B5 B6 NULL +// CHECK-NEXT: Succs (4): B4 B5 B6 B3(Unreachable) // CHECK: [B3] // CHECK-NEXT: default: // CHECK-NEXT: 1: 4 // CHECK-NEXT: 2: x // CHECK-NEXT: 3: [B3.2] = [B3.1] // CHECK-NEXT: T: break; +// CHECK-NEXT: Preds (1): B2(Unreachable) // CHECK-NEXT: Succs (1): B1 // CHECK: [B4] // CHECK-NEXT: case C: