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