// RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks -Wunreachable-code-aggressive -Wno-unused-value -Wno-covered-switch-default -I %S/Inputs #include "warn-unreachable.h" int halt() __attribute__((noreturn)); int live(); int dead(); void test1() { goto c; d: goto e; // expected-warning {{will never be executed}} c: ; int i; return; goto b; // expected-warning {{will never be executed}} goto a; // expected-warning {{will never be executed}} b: i = 1; a: i = 2; goto f; e: goto d; f: ; } void test2() { int i; switch (live()) { case 1: halt(), dead(); // expected-warning {{will never be executed}} case 2: live(), halt(), dead(); // expected-warning {{will never be executed}} case 3: live() + // expected-warning {{will never be executed}} halt(); dead(); case 4: a4: live(), halt(); goto a4; // expected-warning {{will never be executed}} case 5: goto a5; c5: dead(); // expected-warning {{will never be executed}} goto b5; a5: live(), halt(); b5: goto c5; case 6: if (live()) goto e6; live(), halt(); d6: dead(); // expected-warning {{will never be executed}} goto b6; c6: dead(); goto b6; e6: live(), halt(); b6: goto c6; case 7: halt() + dead(); // expected-warning {{will never be executed}} - // expected-warning {{will never be executed}} halt(); case 8: i += // expected-warning {{will never be executed}} halt(); case 9: halt() ? // expected-warning {{will never be executed}} dead() : dead(); case 10: ( // expected-warning {{will never be executed}} float)halt(); case 11: { int a[5]; live(), a[halt() ]; // expected-warning {{will never be executed}} } } } enum Cases { C1, C2, C3 }; int test_enum_cases(enum Cases C) { switch (C) { case C1: case C2: case C3: return 1; default: { int i = 0; // no-warning ++i; return i; } } } // Handle unreachable code triggered by macro expansions. void __myassert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__)); #define myassert(e) \ (__builtin_expect(!(e), 0) ? __myassert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0) void test_assert() { myassert(0 && "unreachable"); return; // no-warning } // Test case for PR 9774. Tests that dead code in macros aren't warned about. #define MY_MAX(a,b) ((a) >= (b) ? (a) : (b)) void PR9774(int *s) { for (int i = 0; i < MY_MAX(2, 3); i++) // no-warning s[i] = 0; } // Test case for <rdar://problem/11005770>. We should treat code guarded // by 'x & 0' and 'x * 0' as unreachable. int calledFun(); void test_mul_and_zero(int x) { if (x & 0) calledFun(); // expected-warning {{will never be executed}} if (0 & x) calledFun(); // expected-warning {{will never be executed}} if (x * 0) calledFun(); // expected-warning {{will never be executed}} if (0 * x) calledFun(); // expected-warning {{will never be executed}} } void raze() __attribute__((noreturn)); void warn_here(); int test_break_preceded_by_noreturn(int i) { switch (i) { case 1: raze(); break; // expected-warning {{'break' will never be executed}} case 2: raze(); break; // expected-warning {{'break' will never be executed}} warn_here(); // expected-warning {{will never be executed}} case 3: return 1; break; // expected-warning {{will never be executed}} default: break; break; // expected-warning {{will never be executed}} } return i; } // Don't warn about unreachable 'default' cases, as that is covered // by -Wcovered-switch-default. typedef enum { Value1 = 1 } MyEnum; void unreachable_default(MyEnum e) { switch (e) { case Value1: calledFun(); break; case 2: // expected-warning {{case value not in enumerated type 'MyEnum'}} calledFun(); break; default: calledFun(); // no-warning break; } } void unreachable_in_default(MyEnum e) { switch (e) { default: raze(); calledFun(); // expected-warning {{will never be executed}} break; } } // Don't warn about trivial dead returns. int trivial_dead_return() { raze(); return ((0)); // expected-warning {{'return' will never be executed}} } void trivial_dead_return_void() { raze(); return; // expected-warning {{'return' will never be executed}} } MyEnum trivial_dead_return_enum() { raze(); return Value1; // expected-warning {{'return' will never be executed}} } MyEnum trivial_dead_return_enum_2(int x) { switch (x) { case 1: return 1; case 2: return 2; case 3: return 3; default: return 4; } return 2; // expected-warning {{will never be executed}} } const char *trivial_dead_return_cstr() { raze(); return ""; // expected-warning {{return' will never be executed}} } char trivial_dead_return_char() { raze(); return ' '; // expected-warning {{return' will never be executed}} } MyEnum nontrivial_dead_return_enum_2(int x) { switch (x) { case 1: return 1; case 2: return 2; case 3: return 3; default: return 4; } return calledFun(); // expected-warning {{will never be executed}} } enum X { A, B, C }; int covered_switch(enum X x) { switch (x) { case A: return 1; case B: return 2; case C: return 3; } return 4; // no-warning } // Test unreachable code depending on configuration values #define CONFIG_CONSTANT 1 int test_config_constant(int x) { if (!CONFIG_CONSTANT) { calledFun(); // no-warning return 1; } if (!1) { // expected-note {{silence by adding parentheses to mark code as explicitly dead}} calledFun(); // expected-warning {{will never be executed}} return 1; } if (sizeof(int) > sizeof(char)) { calledFun(); // no-warning return 1; } if (x > 10) return CONFIG_CONSTANT ? calledFun() : calledFun(); // no-warning else return 1 ? // expected-note {{silence by adding parentheses to mark code as explicitly dead}} calledFun() : calledFun(); // expected-warning {{will never be executed}} } int sizeof_int(int x, int y) { if (sizeof(long) == sizeof(int)) return 1; // no-warning if (sizeof(long) != sizeof(int)) return 0; // no-warning if (x && y && sizeof(long) < sizeof(char)) return 0; // no-warning return 2; // no-warning } enum MyEnum2 { ME_A = CONFIG_CONSTANT, ME_B = 1 }; int test_MyEnum() { if (!ME_A) return 1; // no-warning if (ME_A) return 2; // no-warning if (ME_B) return 3; if (!ME_B) // expected-warning {{will never be executed}} return 4; // expected-warning {{will never be executed}} return 5; } // Test for idiomatic do..while. int test_do_while(int x) { do { if (x == calledFun()) break; ++x; break; } while (0); // no-warning return x; } int test_do_while_nontrivial_cond(int x) { do { if (x == calledFun()) break; ++x; break; } while (calledFun()); // expected-warning {{will never be executed}} return x; } // Diagnostic control: -Wunreachable-code-return. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunreachable-code-return" void trivial_dead_return_void_SUPPRESSED() { raze(); return; // no-warning } MyEnum trivial_dead_return_enum_SUPPRESSED() { raze(); return Value1; // no-warning } #pragma clang diagnostic pop // Diagnostic control: -Wunreachable-code-break. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunreachable-code-break" int test_break_preceded_by_noreturn_SUPPRESSED(int i) { switch (i) { case 1: raze(); break; // no-warning case 2: raze(); break; // no-warning warn_here(); // expected-warning {{will never be executed}} case 3: return 1; break; // no-warning default: break; break; // no-warning } return i; } #pragma clang diagnostic pop // Test "silencing" with parentheses. void test_with_paren_silencing(int x) { if (0) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}} if ((0)) calledFun(); // no-warning if (1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}} calledFun(); else calledFun(); // expected-warning {{will never be executed}} if ((1)) calledFun(); else calledFun(); // no-warning if (!1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}} calledFun(); // expected-warning {{code will never be executed}} else calledFun(); if ((!1)) calledFun(); // no-warning else calledFun(); if (!(1)) calledFun(); // no-warning else calledFun(); }