1 // RUN: %clang_analyze_cc1 -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 7 void 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 18 void 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 28 void 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 37 void 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 52 void 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 62 void 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 }; 71 void 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 82 void 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 92 void 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 107 void 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(); 130 void 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 143 void inlined(int condition) { 144 if (condition) { 145 foo(5); // no-warning 146 } else { 147 foo(6); 148 } 149 } 150 151 void 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 162 // Don't warn about unreachable VarDecl. 163 void dostuff(int*A); 164 void varDecl1(int X) { 165 switch (X) { 166 int A; // No warning here. 167 case 1: 168 dostuff(&A); 169 break; 170 case 2: 171 dostuff(&A); 172 break; 173 } 174 } 175 void varDecl2(int X) { 176 switch (X) { 177 int A=1; // expected-warning {{never executed}} 178 case 1: 179 dostuff(&A); 180 break; 181 case 2: 182 dostuff(&A); 183 break; 184 } 185 } 186 187 // Ensure that ExplodedGraph and unoptimized CFG match. 188 void test12(int x) { 189 switch (x) { 190 case 1: 191 break; // not unreachable 192 case 2: 193 do { } while (0); 194 break; 195 } 196 } 197 198 // Don't merge return nodes in ExplodedGraph unless they are same. 199 extern int table[]; 200 static int inlineFunction(const int i) { 201 if (table[i] != 0) 202 return 1; 203 return 0; 204 } 205 void test13(int i) { 206 int x = inlineFunction(i); 207 x && x < 10; // no-warning 208 } 209 210 // Don't warn in a macro 211 #define RETURN(X) do { return; } while (0) 212 void macro(void) { 213 RETURN(1); // no-warning 214 } 215 216