314 lines · cpp
1// RUN: %clang_cc1 -Wno-error=return-type -fsyntax-only -verify %s2 3// Reachability tests have to come first because they get suppressed4// if any errors have occurred.5namespace test5 {6 struct A {7 __attribute__((noreturn)) void fail();8 void nofail();9 } a;10 11 int &test1() {12 a.nofail();13 } // expected-warning {{non-void function does not return a value}}14 15 int &test2() {16 a.fail();17 }18}19 20namespace destructor_tests {21 __attribute__((noreturn)) void fail();22 23 struct A {24 ~A() __attribute__((noreturn)) { fail(); }25 };26 struct B {27 B() {}28 ~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 44 __attribute__((noreturn)) void test_1() { A a; }45 __attribute__((noreturn)) void test_2() { B b; }46 __attribute__((noreturn)) void test_3() { C c; }47 __attribute__((noreturn)) void test_4() { D d; }48 __attribute__((noreturn)) void test_5() { E e; }49 __attribute__((noreturn)) void test_6() { F f; }50 __attribute__((noreturn)) void test_7() { G g; }51 __attribute__((noreturn)) void test_8() { H h; }52 __attribute__((noreturn)) void test_9() { I i; }53 __attribute__((noreturn)) void test_10() { J j; }54 __attribute__((noreturn)) void test_11() { K k; }55 __attribute__((noreturn)) void test_12() { L l; }56 __attribute__((noreturn)) void test_13() { M m; }57 __attribute__((noreturn)) void test_14() { N n; }58 __attribute__((noreturn)) void test_15() { O o; }59 60 __attribute__((noreturn)) void test_16() { const A& a = A(); }61 __attribute__((noreturn)) void test_17() { const B& b = B(); }62 __attribute__((noreturn)) void test_18() { const C& c = C(); }63 __attribute__((noreturn)) void test_19() { const D& d = D(); }64 __attribute__((noreturn)) void test_20() { const E& e = E(); }65 __attribute__((noreturn)) void test_21() { const F& f = F(); }66 __attribute__((noreturn)) void test_22() { const G& g = G(); }67 __attribute__((noreturn)) void test_23() { const H& h = H(); }68 __attribute__((noreturn)) void test_24() { const I& i = I(); }69 __attribute__((noreturn)) void test_25() { const J& j = J(); }70 __attribute__((noreturn)) void test_26() { const K& k = K(); }71 __attribute__((noreturn)) void test_27() { const L& l = L(); }72 __attribute__((noreturn)) void test_28() { const M& m = M(); }73 __attribute__((noreturn)) void test_29() { const N& n = N(); }74 __attribute__((noreturn)) void test_30() { const O& o = O(); }75 76 struct AA {};77 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 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 {127 ~P() __attribute__((noreturn)) { fail(); }128 void foo() {}129 };130 struct Q : P { };131 __attribute__((noreturn)) void test31() {132 P().foo();133 }134 __attribute__((noreturn)) void test32() {135 Q().foo();136 }137 138 struct R {139 A a[5];140 };141 __attribute__((noreturn)) void test33() {142 R r;143 }144 145 // FIXME: Code flow analysis does not preserve information about non-null146 // pointers, so it can't determine that this function is noreturn.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-null160 // pointers or derived class pointers, so it can't determine that this161 // function is noreturn.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// PR5620169void f0() __attribute__((__noreturn__));170void f1(void (*)());171void f2() { f1(f0); }172 173// Taking the address of a noreturn function174void test_f0a() {175 void (*fp)() = f0;176 void (*fp1)() __attribute__((noreturn)) = f0;177}178 179// Taking the address of an overloaded noreturn function 180void f0(int) __attribute__((__noreturn__));181 182void test_f0b() {183 void (*fp)() = f0;184 void (*fp1)() __attribute__((noreturn)) = f0;185}186 187// No-returned function pointers188typedef void (* noreturn_fp)() __attribute__((noreturn));189 190void f3(noreturn_fp); // expected-note{{candidate function}}191 192void test_f3() {193 f3(f0); // okay194 f3(f2); // expected-error{{no matching function for call}}195}196 197 198class xpto {199 int blah() __attribute__((noreturn));200};201 202int xpto::blah() {203 return 3; // expected-warning {{function 'blah' declared 'noreturn' should not return}}204}205 206// PR12948207 208namespace PR12948 {209 template<int>210 void foo() __attribute__((__noreturn__));211 212 template<int>213 void foo() {214 while (1) continue;215 }216 217 void bar() __attribute__((__noreturn__));218 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// PR15291233// Overload resolution per over.over should allow implicit noreturn adjustment.234namespace PR15291 {235 __attribute__((noreturn)) void foo(int) {}236 __attribute__((noreturn)) void foo(double) {}237 238 template <typename T>239 __attribute__((noreturn)) void bar(T) {}240 241 void baz(int) {}242 void baz(double) {}243 244 template <typename T>245 void qux(T) {}246 247 // expected-note@+5 {{candidate function template not viable: no overload of 'baz' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}248 // expected-note@+4 {{candidate function template not viable: no overload of 'qux' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}249 // expected-note@+3 {{candidate function template not viable: no overload of 'bar' matching 'void (*)(int) __attribute__((noreturn))' for 1st argument}}250 // expected-note@+2 {{candidate function template not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}251 // expected-note@+1 {{candidate function template not viable: no overload of 'bar' matching 'void (*)(int)' for 1st argument}}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}}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}}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}}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}}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.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.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