1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 3 // Reachability tests have to come first because they get suppressed 4 // if any errors have occurred. 5 namespace test5 { 6 struct A { 7 __attribute__((noreturn)) void fail(); 8 void nofail(); 9 } a; 10 test1()11 int &test1() { 12 a.nofail(); 13 } // expected-warning {{control reaches end of non-void function}} 14 test2()15 int &test2() { 16 a.fail(); 17 } 18 } 19 20 namespace destructor_tests { 21 __attribute__((noreturn)) void fail(); 22 23 struct A { ~Adestructor_tests::A24 ~A() __attribute__((noreturn)) { fail(); } 25 }; 26 struct B { Bdestructor_tests::B27 B() {} ~Bdestructor_tests::B28 ~B() __attribute__((noreturn)) { fail(); } 29 }; 30 struct C : A {}; 31 struct D : B {}; 32 struct E : virtual A {}; 33 struct F : A, virtual B {}; 34 struct G : E {}; 35 struct H : virtual D {}; 36 struct I : A {}; 37 struct J : I {}; 38 struct K : virtual A {}; 39 struct L : K {}; 40 struct M : virtual C {}; 41 struct N : M {}; 42 struct O { N n; }; 43 test_1()44 __attribute__((noreturn)) void test_1() { A a; } test_2()45 __attribute__((noreturn)) void test_2() { B b; } test_3()46 __attribute__((noreturn)) void test_3() { C c; } test_4()47 __attribute__((noreturn)) void test_4() { D d; } test_5()48 __attribute__((noreturn)) void test_5() { E e; } test_6()49 __attribute__((noreturn)) void test_6() { F f; } test_7()50 __attribute__((noreturn)) void test_7() { G g; } test_8()51 __attribute__((noreturn)) void test_8() { H h; } test_9()52 __attribute__((noreturn)) void test_9() { I i; } test_10()53 __attribute__((noreturn)) void test_10() { J j; } test_11()54 __attribute__((noreturn)) void test_11() { K k; } test_12()55 __attribute__((noreturn)) void test_12() { L l; } test_13()56 __attribute__((noreturn)) void test_13() { M m; } test_14()57 __attribute__((noreturn)) void test_14() { N n; } test_15()58 __attribute__((noreturn)) void test_15() { O o; } 59 test_16()60 __attribute__((noreturn)) void test_16() { const A& a = A(); } test_17()61 __attribute__((noreturn)) void test_17() { const B& b = B(); } test_18()62 __attribute__((noreturn)) void test_18() { const C& c = C(); } test_19()63 __attribute__((noreturn)) void test_19() { const D& d = D(); } test_20()64 __attribute__((noreturn)) void test_20() { const E& e = E(); } test_21()65 __attribute__((noreturn)) void test_21() { const F& f = F(); } test_22()66 __attribute__((noreturn)) void test_22() { const G& g = G(); } test_23()67 __attribute__((noreturn)) void test_23() { const H& h = H(); } test_24()68 __attribute__((noreturn)) void test_24() { const I& i = I(); } test_25()69 __attribute__((noreturn)) void test_25() { const J& j = J(); } test_26()70 __attribute__((noreturn)) void test_26() { const K& k = K(); } test_27()71 __attribute__((noreturn)) void test_27() { const L& l = L(); } test_28()72 __attribute__((noreturn)) void test_28() { const M& m = M(); } test_29()73 __attribute__((noreturn)) void test_29() { const N& n = N(); } test_30()74 __attribute__((noreturn)) void test_30() { const O& o = O(); } 75 76 struct AA {}; BBdestructor_tests::BB77 struct BB { BB() {} ~BB() {} }; 78 struct CC : AA {}; 79 struct DD : BB {}; 80 struct EE : virtual AA {}; 81 struct FF : AA, virtual BB {}; 82 struct GG : EE {}; 83 struct HH : virtual DD {}; 84 struct II : AA {}; 85 struct JJ : II {}; 86 struct KK : virtual AA {}; 87 struct LL : KK {}; 88 struct MM : virtual CC {}; 89 struct NN : MM {}; 90 struct OO { NN n; }; 91 test_31()92 __attribute__((noreturn)) void test_31() { 93 AA a; 94 BB b; 95 CC c; 96 DD d; 97 EE e; 98 FF f; 99 GG g; 100 HH h; 101 II i; 102 JJ j; 103 KK k; 104 LL l; 105 MM m; 106 NN n; 107 OO o; 108 109 const AA& aa = AA(); 110 const BB& bb = BB(); 111 const CC& cc = CC(); 112 const DD& dd = DD(); 113 const EE& ee = EE(); 114 const FF& ff = FF(); 115 const GG& gg = GG(); 116 const HH& hh = HH(); 117 const II& ii = II(); 118 const JJ& jj = JJ(); 119 const KK& kk = KK(); 120 const LL& ll = LL(); 121 const MM& mm = MM(); 122 const NN& nn = NN(); 123 const OO& oo = OO(); 124 } // expected-warning {{function declared 'noreturn' should not return}} 125 126 struct P { ~Pdestructor_tests::P127 ~P() __attribute__((noreturn)) { fail(); } foodestructor_tests::P128 void foo() {} 129 }; 130 struct Q : P { }; test31()131 __attribute__((noreturn)) void test31() { 132 P().foo(); 133 } test32()134 __attribute__((noreturn)) void test32() { 135 Q().foo(); 136 } 137 138 struct R { 139 A a[5]; 140 }; test33()141 __attribute__((noreturn)) void test33() { 142 R r; 143 } 144 145 // FIXME: Code flow analysis does not preserve information about non-null 146 // pointers, so it can't determine that this function is noreturn. test34()147 __attribute__((noreturn)) void test34() { 148 A *a = new A; 149 delete a; 150 } // expected-warning {{function declared 'noreturn' should not return}} 151 152 struct S { 153 virtual ~S(); 154 }; 155 struct T : S { 156 __attribute__((noreturn)) ~T(); 157 }; 158 159 // FIXME: Code flow analysis does not preserve information about non-null 160 // pointers or derived class pointers, so it can't determine that this 161 // function is noreturn. test35()162 __attribute__((noreturn)) void test35() { 163 S *s = new T; 164 delete s; 165 } // expected-warning {{function declared 'noreturn' should not return}} 166 } 167 168 // PR5620 169 void f0() __attribute__((__noreturn__)); 170 void f1(void (*)()); f2()171void f2() { f1(f0); } 172 173 // Taking the address of a noreturn function test_f0a()174void test_f0a() { 175 void (*fp)() = f0; 176 void (*fp1)() __attribute__((noreturn)) = f0; 177 } 178 179 // Taking the address of an overloaded noreturn function 180 void f0(int) __attribute__((__noreturn__)); 181 test_f0b()182void test_f0b() { 183 void (*fp)() = f0; 184 void (*fp1)() __attribute__((noreturn)) = f0; 185 } 186 187 // No-returned function pointers 188 typedef void (* noreturn_fp)() __attribute__((noreturn)); 189 190 void f3(noreturn_fp); // expected-note{{candidate function}} 191 test_f3()192void test_f3() { 193 f3(f0); // okay 194 f3(f2); // expected-error{{no matching function for call}} 195 } 196 197 198 class xpto { 199 int blah() __attribute__((noreturn)); 200 }; 201 blah()202int xpto::blah() { 203 return 3; // expected-warning {{function 'blah' declared 'noreturn' should not return}} 204 } 205 206 // PR12948 207 208 namespace PR12948 { 209 template<int> 210 void foo() __attribute__((__noreturn__)); 211 212 template<int> foo()213 void foo() { 214 while (1) continue; 215 } 216 217 void bar() __attribute__((__noreturn__)); 218 bar()219 void bar() { 220 foo<0>(); 221 } 222 223 224 void baz() __attribute__((__noreturn__)); 225 typedef void voidfn(); 226 voidfn baz; 227 228 template<typename> void wibble() __attribute__((__noreturn__)); 229 template<typename> voidfn wibble; 230 } 231 232 // PR15291 233 // Overload resolution per over.over should allow implicit noreturn adjustment. 234 namespace PR15291 { foo(int)235 __attribute__((noreturn)) void foo(int) {} foo(double)236 __attribute__((noreturn)) void foo(double) {} 237 238 template <typename T> bar(T)239 __attribute__((noreturn)) void bar(T) {} 240 baz(int)241 void baz(int) {} baz(double)242 void baz(double) {} 243 244 template <typename T> qux(T)245 void qux(T) {} 246 247 // expected-note@+5 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} 248 // expected-note@+4 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} 249 // expected-note@+3 {{candidate function [with T = void (*)(int) __attribute__((noreturn))] not viable: no overload of 'bar' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} 250 // expected-note@+2 {{candidate function [with T = void (*)(int)] not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}} 251 // expected-note@+1 {{candidate function [with T = void (int)] not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}} accept_T(T)252 template <typename T> void accept_T(T) {} 253 254 // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}} accept_fptr(void (* f)(int))255 void accept_fptr(void (*f)(int)) { 256 f(42); 257 } 258 259 // expected-note@+2 {{candidate function not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} 260 // expected-note@+1 {{candidate function not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}} accept_noreturn_fptr(void (* f)(int))261 void accept_noreturn_fptr(void __attribute__((noreturn)) (*f)(int)) { 262 f(42); 263 } 264 265 typedef void (*fptr_t)(int); 266 typedef void __attribute__((noreturn)) (*fptr_noreturn_t)(int); 267 268 // expected-note@+1 {{candidate function not viable: no overload of 'bar' matching 'fptr_t' (aka 'void (*)(int)') for 1st argument}} accept_fptr_t(fptr_t f)269 void accept_fptr_t(fptr_t f) { 270 f(42); 271 } 272 273 // expected-note@+2 {{candidate function not viable: no overload of 'baz' matching 'fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}} 274 // expected-note@+1 {{candidate function not viable: no overload of 'qux' matching 'fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}} accept_fptr_noreturn_t(fptr_noreturn_t f)275 void accept_fptr_noreturn_t(fptr_noreturn_t f) { 276 f(42); 277 } 278 279 // Stripping noreturn should work if everything else is correct. strip_noreturn()280 void strip_noreturn() { 281 accept_fptr(foo); 282 accept_fptr(bar<int>); 283 accept_fptr(bar<double>); // expected-error {{no matching function for call to 'accept_fptr'}} 284 285 accept_fptr_t(foo); 286 accept_fptr_t(bar<int>); 287 accept_fptr_t(bar<double>); // expected-error {{no matching function for call to 'accept_fptr_t'}} 288 289 accept_T<void __attribute__((noreturn)) (*)(int)>(foo); 290 accept_T<void __attribute__((noreturn)) (*)(int)>(bar<int>); 291 accept_T<void __attribute__((noreturn)) (*)(int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}} 292 293 accept_T<void (*)(int)>(foo); 294 accept_T<void (*)(int)>(bar<int>); 295 accept_T<void (*)(int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}} 296 297 accept_T<void (int)>(foo); 298 accept_T<void (int)>(bar<int>); 299 accept_T<void (int)>(bar<double>); // expected-error {{no matching function for call to 'accept_T'}} 300 } 301 302 // Introducing noreturn should not work. introduce_noreturn()303 void introduce_noreturn() { 304 accept_noreturn_fptr(baz); // expected-error {{no matching function for call to 'accept_noreturn_fptr'}} 305 accept_noreturn_fptr(qux<int>); // expected-error {{no matching function for call to 'accept_noreturn_fptr'}} 306 307 accept_fptr_noreturn_t(baz); // expected-error {{no matching function for call to 'accept_fptr_noreturn_t'}} 308 accept_fptr_noreturn_t(qux<int>); // expected-error {{no matching function for call to 'accept_fptr_noreturn_t'}} 309 310 accept_T<void __attribute__((noreturn)) (*)(int)>(baz); // expected-error {{no matching function for call to 'accept_T'}} 311 accept_T<void __attribute__((noreturn)) (*)(int)>(qux<int>); // expected-error {{no matching function for call to 'accept_T'}} 312 } 313 } 314