From: Ted Kremenek Date: Thu, 6 Mar 2014 08:09:00 +0000 (+0000) Subject: [-Wunreachable-code] Refine treating all branches of 'switch' as reachable, which... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f24be6fc836d88703f90128567be0bba07fc3b0d;p=clang [-Wunreachable-code] Refine treating all branches of 'switch' as reachable, which includes those with all cases covered but with no 'default:'. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@203094 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp index 79e8d8cb01..45930c0e2d 100644 --- a/lib/Analysis/ReachableCode.cpp +++ b/lib/Analysis/ReachableCode.cpp @@ -457,6 +457,10 @@ static bool isConfigurationValue(const Stmt *S) { /// Returns true if we should always explore all successors of a block. static bool shouldTreatSuccessorsAsReachable(const CFGBlock *B) { + if (const Stmt *Term = B->getTerminator()) + if (isa(Term)) + return true; + return isConfigurationValue(B->getTerminatorCondition()); } @@ -500,24 +504,6 @@ unsigned ScanReachableFromBlock(const CFGBlock *Start, B = UB; break; } - - // 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. - // - const Stmt *Label = UB->getLabel(); - if (Label && isa(Label)) - B = UB; } while (false); diff --git a/test/Sema/warn-unreachable.c b/test/Sema/warn-unreachable.c index fe47e4c6b7..289d74336c 100644 --- a/test/Sema/warn-unreachable.c +++ b/test/Sema/warn-unreachable.c @@ -226,6 +226,17 @@ MyEnum nontrivial_dead_return_enum_2(int x) { return calledFun(); // expected-warning {{will never be executed}} } +enum X { A, B, C }; + +int covered_switch(enum X x) { + switch (x) { + case A: return 1; + case B: return 2; + case C: return 3; + } + return 4; // no-warning +} + // Test unreachable code depending on configuration values #define CONFIG_CONSTANT 1 int test_config_constant(int x) {