warn-unreachable.cpp revision a9bb955b499c244d24d02311f0f9100ade506794
1// RUN: %clang_cc1 %s -fcxx-exceptions -fexceptions -fsyntax-only -verify -fblocks -Wunreachable-code -Wno-unused-value 2 3int &halt() __attribute__((noreturn)); 4int &live(); 5int dead(); 6int liveti() throw(int); 7int (*livetip)() throw(int); 8 9int test1() { 10 try { 11 live(); 12 } catch (int i) { 13 live(); 14 } 15 return 1; 16} 17 18void test2() { 19 try { 20 live(); 21 } catch (int i) { 22 live(); 23 } 24 try { 25 liveti(); 26 } catch (int i) { 27 live(); 28 } 29 try { 30 livetip(); 31 } catch (int i) { 32 live(); 33 } 34 throw 1; 35 dead(); // expected-warning {{will never be executed}} 36} 37 38 39void test3() { 40 halt() 41 --; // expected-warning {{will never be executed}} 42 // FIXME: The unreachable part is just the '?', but really all of this 43 // code is unreachable and shouldn't be separately reported. 44 halt() // expected-warning {{will never be executed}} 45 ? 46 dead() : dead(); 47 live(), 48 float 49 (halt()); // expected-warning {{will never be executed}} 50} 51 52void test4() { 53 struct S { 54 int mem; 55 } s; 56 S &foor(); 57 halt(), foor()// expected-warning {{will never be executed}} 58 .mem; 59} 60 61void test5() { 62 struct S { 63 int mem; 64 } s; 65 S &foor() __attribute__((noreturn)); 66 foor() 67 .mem; // expected-warning {{will never be executed}} 68} 69 70void test6() { 71 struct S { 72 ~S() { } 73 S(int i) { } 74 }; 75 live(), 76 S 77 (halt()); // expected-warning {{will never be executed}} 78} 79 80// Don't warn about unreachable code in template instantiations, as 81// they may only be unreachable in that specific instantiation. 82void isUnreachable(); 83 84template <typename T> void test_unreachable_templates() { 85 T::foo(); 86 isUnreachable(); // no-warning 87} 88 89struct TestUnreachableA { 90 static void foo() __attribute__((noreturn)); 91}; 92struct TestUnreachableB { 93 static void foo(); 94}; 95 96void test_unreachable_templates_harness() { 97 test_unreachable_templates<TestUnreachableA>(); 98 test_unreachable_templates<TestUnreachableB>(); 99} 100 101// Do warn about non-dependent unreachable code in templates 102// Warn even if the template is never instantiated 103 104template<typename T> void test_non_dependent_unreachable_templates() { 105 TestUnreachableA::foo(); 106 isUnreachable(); // expected-warning {{will never be executed}} 107} 108 109// Warn only once even if the template is instantiated multiple times 110 111template<typename T> void test_non_dependent_unreachable_templates2() { 112 TestUnreachableA::foo(); 113 isUnreachable(); // expected-warning {{will never be executed}} 114} 115 116template void test_non_dependent_unreachable_templates2<int>(); 117template void test_non_dependent_unreachable_templates2<long>(); 118 119// Do warn about explict template specializations, as they represent 120// actual concrete functions that somebody wrote. 121 122template <typename T> void funcToSpecialize() {} 123template <> void funcToSpecialize<int>() { 124 halt(); 125 dead(); // expected-warning {{will never be executed}} 126} 127 128// Ensure we don't regress a fix involving undefined bases to template 129// destructors when computing the CFG for unreachable code analysis 130template<int> struct imp; 131template<int a> 132struct aligned_storage : imp<a> { 133 ~aligned_storage() { } 134}; 135 136// is this valid? 137template<typename T> 138class outer { 139 class inner; 140 void func() { 141 inner t; 142 } 143}; 144