// RUN: %clang_cc1 %s -fcxx-exceptions -fexceptions -fsyntax-only -verify -fblocks -Wunreachable-code -Wno-unused-value int &halt() __attribute__((noreturn)); int &live(); int dead(); int liveti() throw(int); int (*livetip)() throw(int); int test1() { try { live(); } catch (int i) { live(); } return 1; } void test2() { try { live(); } catch (int i) { live(); } try { liveti(); } catch (int i) { live(); } try { livetip(); } catch (int i) { live(); } throw 1; dead(); // expected-warning {{will never be executed}} } void test3() { halt() --; // expected-warning {{will never be executed}} // FIXME: The unreachable part is just the '?', but really all of this // code is unreachable and shouldn't be separately reported. halt() // expected-warning {{will never be executed}} ? dead() : dead(); live(), float (halt()); // expected-warning {{will never be executed}} } void test4() { struct S { int mem; } s; S &foor(); halt(), foor()// expected-warning {{will never be executed}} .mem; } void test5() { struct S { int mem; } s; S &foor() __attribute__((noreturn)); foor() .mem; // expected-warning {{will never be executed}} } void test6() { struct S { ~S() { } S(int i) { } }; live(), S (halt()); // expected-warning {{will never be executed}} } // Don't warn about unreachable code in template instantiations, as // they may only be unreachable in that specific instantiation. void isUnreachable(); template <typename T> void test_unreachable_templates() { T::foo(); isUnreachable(); // no-warning } struct TestUnreachableA { static void foo() __attribute__((noreturn)); }; struct TestUnreachableB { static void foo(); }; void test_unreachable_templates_harness() { test_unreachable_templates<TestUnreachableA>(); test_unreachable_templates<TestUnreachableB>(); } // Do warn about explict template specializations, as they represent // actual concrete functions that somebody wrote. template <typename T> void funcToSpecialize() {} template <> void funcToSpecialize<int>() { halt(); dead(); // expected-warning {{will never be executed}} }