| // RUN: %clang_cc1 -analyze -analyzer-checker=core,deadcode.DeadStores,experimental.deadcode.UnreachableCode -verify -analyzer-opt-analyze-nested-blocks -Wno-unused-value %s | 
 |  | 
 | extern void foo(int a); | 
 |  | 
 | // The first few tests are non-path specific - we should be able to find them | 
 |  | 
 | void test(unsigned a) { | 
 |   switch (a) { | 
 |     a += 5; // expected-warning{{never executed}} | 
 |   case 2: | 
 |     a *= 10; | 
 |   case 3: | 
 |     a %= 2; | 
 |   } | 
 |   foo(a); | 
 | } | 
 |  | 
 | void test2(unsigned a) { | 
 |  help: | 
 |   if (a > 0) | 
 |     return; | 
 |   if (a == 0) | 
 |     return; | 
 |   foo(a); // expected-warning{{never executed}} | 
 |   goto help; | 
 | } | 
 |  | 
 | void test3(unsigned a) { | 
 |   while(1); | 
 |   if (a > 5) { // expected-warning{{never executed}} | 
 |     return; | 
 |   } | 
 | } | 
 |  | 
 | // These next tests are path-sensitive | 
 |  | 
 | void test4() { | 
 |   int a = 5; | 
 |  | 
 |   while (a > 1) | 
 |     a -= 2; | 
 |  | 
 |   if (a > 1) { | 
 |     a = a + 56; // expected-warning{{never executed}} | 
 |   } | 
 |  | 
 |   foo(a); | 
 | } | 
 |  | 
 | extern void bar(char c); | 
 |  | 
 | void test5(const char *c) { | 
 |   foo(c[0]); | 
 |  | 
 |   if (!c) { | 
 |     bar(1); // expected-warning{{never executed}} | 
 |   } | 
 | } | 
 |  | 
 | // These next tests are false positives and should not generate warnings | 
 |  | 
 | void test6(const char *c) { | 
 |   if (c) return; | 
 |   if (!c) return; | 
 |   __builtin_unreachable(); // no-warning | 
 | } | 
 |  | 
 | // Compile-time constant false positives | 
 | #define CONSTANT 0 | 
 | enum test_enum { Off, On }; | 
 | void test7() { | 
 |   if (CONSTANT) | 
 |     return; // no-warning | 
 |  | 
 |   if (sizeof(int)) | 
 |     return; // no-warning | 
 |  | 
 |   if (Off) | 
 |     return; // no-warning | 
 | } | 
 |  | 
 | void test8() { | 
 |   static unsigned a = 0; | 
 |  | 
 |   if (a) | 
 |     a = 123; // no-warning | 
 |  | 
 |   a = 5; | 
 | } | 
 |  | 
 | // Check for bugs where multiple statements are reported | 
 | void test9(unsigned a) { | 
 |   switch (a) { | 
 |     if (a) // expected-warning{{never executed}} | 
 |       foo(a + 5); // no-warning | 
 |     else          // no-warning | 
 |       foo(a);     // no-warning | 
 |     case 1: | 
 |     case 2: | 
 |       break; | 
 |     default: | 
 |       break; | 
 |   } | 
 | } | 
 |  | 
 | // Tests from flow-sensitive version | 
 | void test10() { | 
 |   goto c; | 
 |   d: | 
 |   goto e; // expected-warning {{never executed}} | 
 |   c: ; | 
 |   int i; | 
 |   return; | 
 |   goto b; // expected-warning {{never executed}} | 
 |   goto a; // expected-warning {{never executed}} | 
 |   b: | 
 |   i = 1; // no-warning | 
 |   a: | 
 |   i = 2;  // no-warning | 
 |   goto f; | 
 |   e: | 
 |   goto d; | 
 |   f: ; | 
 | } |