// RUN: %clang_cc1 -analyze -analyzer-checker=core,deadcode.DeadStores,alpha.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: ; } // test11: we can actually end up in the default case, even if it is not // obvious: there might be something wrong with the given argument. enum foobar { FOO, BAR }; extern void error(); void test11(enum foobar fb) { switch (fb) { case FOO: break; case BAR: break; default: error(); // no-warning return; error(); // expected-warning {{never executed}} } } void inlined(int condition) { if (condition) { foo(5); // no-warning } else { foo(6); } } void testInlined() { extern int coin(); int cond = coin(); if (!cond) { inlined(0); if (cond) { foo(5); // expected-warning {{never executed}} } } }