1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,deadcode.DeadStores,alpha.deadcode.UnreachableCode -verify -analyzer-opt-analyze-nested-blocks -Wno-unused-value %s 2 3 extern void foo(int a); 4 5 // The first few tests are non-path specific - we should be able to find them 6 test(unsigned a)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 test2(unsigned a)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 test3(unsigned a)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 test4()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 50 extern void bar(char c); 51 test5(const char * c)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 test6(const char * c)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 70 enum test_enum { Off, On }; test7()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 test8()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 test9(unsigned a)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 test10()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. 128 enum foobar { FOO, BAR }; 129 extern void error(); test11(enum foobar fb)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 inlined(int condition)143void inlined(int condition) { 144 if (condition) { 145 foo(5); // no-warning 146 } else { 147 foo(6); 148 } 149 } 150 testInlined()151void testInlined() { 152 extern int coin(); 153 int cond = coin(); 154 if (!cond) { 155 inlined(0); 156 if (cond) { 157 foo(5); // expected-warning {{never executed}} 158 } 159 } 160 } 161