1// RUN: %clang_cc1 -analyze -analyzer-checker=core,deadcode.DeadStores,alpha.deadcode.UnreachableCode -verify -analyzer-opt-analyze-nested-blocks -Wno-unused-value %s 2 3extern void foo(int a); 4 5// The first few tests are non-path specific - we should be able to find them 6 7void test(unsigned a) { 8 switch (a) { 9 a += 5; // expected-warning{{never executed}} 10 case 2: 11 a *= 10; 12 case 3: 13 a %= 2; 14 } 15 foo(a); 16} 17 18void test2(unsigned a) { 19 help: 20 if (a > 0) 21 return; 22 if (a == 0) 23 return; 24 foo(a); // expected-warning{{never executed}} 25 goto help; 26} 27 28void test3(unsigned a) { 29 while(1); 30 if (a > 5) { // expected-warning{{never executed}} 31 return; 32 } 33} 34 35// These next tests are path-sensitive 36 37void test4() { 38 int a = 5; 39 40 while (a > 1) 41 a -= 2; 42 43 if (a > 1) { 44 a = a + 56; // expected-warning{{never executed}} 45 } 46 47 foo(a); 48} 49 50extern void bar(char c); 51 52void test5(const char *c) { 53 foo(c[0]); 54 55 if (!c) { 56 bar(1); // expected-warning{{never executed}} 57 } 58} 59 60// These next tests are false positives and should not generate warnings 61 62void test6(const char *c) { 63 if (c) return; 64 if (!c) return; 65 __builtin_unreachable(); // no-warning 66} 67 68// Compile-time constant false positives 69#define CONSTANT 0 70enum test_enum { Off, On }; 71void test7() { 72 if (CONSTANT) 73 return; // no-warning 74 75 if (sizeof(int)) 76 return; // no-warning 77 78 if (Off) 79 return; // no-warning 80} 81 82void test8() { 83 static unsigned a = 0; 84 85 if (a) 86 a = 123; // no-warning 87 88 a = 5; 89} 90 91// Check for bugs where multiple statements are reported 92void test9(unsigned a) { 93 switch (a) { 94 if (a) // expected-warning{{never executed}} 95 foo(a + 5); // no-warning 96 else // no-warning 97 foo(a); // no-warning 98 case 1: 99 case 2: 100 break; 101 default: 102 break; 103 } 104} 105 106// Tests from flow-sensitive version 107void test10() { 108 goto c; 109 d: 110 goto e; // expected-warning {{never executed}} 111 c: ; 112 int i; 113 return; 114 goto b; // expected-warning {{never executed}} 115 goto a; // expected-warning {{never executed}} 116 b: 117 i = 1; // no-warning 118 a: 119 i = 2; // no-warning 120 goto f; 121 e: 122 goto d; 123 f: ; 124} 125 126// test11: we can actually end up in the default case, even if it is not 127// obvious: there might be something wrong with the given argument. 128enum foobar { FOO, BAR }; 129extern void error(); 130void test11(enum foobar fb) { 131 switch (fb) { 132 case FOO: 133 break; 134 case BAR: 135 break; 136 default: 137 error(); // no-warning 138 return; 139 error(); // expected-warning {{never executed}} 140 } 141} 142