aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/ReachableCode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Analysis/ReachableCode.cpp')
-rw-r--r--clang/lib/Analysis/ReachableCode.cpp35
1 files changed, 27 insertions, 8 deletions
diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp
index 797e02e..4a19280 100644
--- a/clang/lib/Analysis/ReachableCode.cpp
+++ b/clang/lib/Analysis/ReachableCode.cpp
@@ -337,12 +337,6 @@ void DeadCodeScan::reportDeadCode(const CFGBlock *B,
if (isTrivialReturnPrecededByNoReturn(B, S))
return;
- // Was this an unreachable 'default' case? Such cases are covered
- // by -Wcovered-switch-default, if the user so desires.
- const Stmt *Label = B->getLabel();
- if (Label && isa<DefaultStmt>(Label))
- return;
-
SourceRange R1, R2;
SourceLocation Loc = GetUnreachableLoc(S, R1, R2);
CB.HandleUnreachable(Loc, R1, R2);
@@ -374,8 +368,32 @@ unsigned ScanReachableFromBlock(const CFGBlock *Start,
// Look at the successors and mark then reachable.
for (CFGBlock::const_succ_iterator I = item->succ_begin(),
- E = item->succ_end(); I != E; ++I)
- if (const CFGBlock *B = *I) {
+ E = item->succ_end(); I != E; ++I) {
+ const CFGBlock *B = *I;
+ if (!B) {
+ //
+ // For switch statements, treat all cases as being reachable.
+ // There are many cases where a switch can contain values that
+ // are not in an enumeration but they are still reachable because
+ // other values are possible.
+ //
+ // Note that this is quite conservative. If one saw:
+ //
+ // switch (1) {
+ // case 2: ...
+ //
+ // we should be able to say that 'case 2' is unreachable. To do
+ // this we can either put more heuristics here, or possibly retain
+ // that information in the CFG itself.
+ //
+ if (const CFGBlock *UB = I->getPossiblyUnreachableBlock()) {
+ const Stmt *Label = UB->getLabel();
+ if (Label && isa<SwitchCase>(Label)) {
+ B = UB;
+ }
+ }
+ }
+ if (B) {
unsigned blockID = B->getBlockID();
if (!Reachable[blockID]) {
Reachable.set(blockID);
@@ -383,6 +401,7 @@ unsigned ScanReachableFromBlock(const CFGBlock *Start,
++count;
}
}
+ }
}
return count;
}