[CFG] record the original (now unreachable) block of 'case:' and 'default:' cases.

llvm-svn: 202435
This commit is contained in:
Ted Kremenek 2014-02-27 21:56:44 +00:00
parent 4b408e7a04
commit 9238c5c878
2 changed files with 25 additions and 13 deletions

View File

@ -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';

View File

@ -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: