• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()171 void f2() { f1(f0); }
172 
173 // Taking the address of a noreturn function
test_f0a()174 void 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()182 void 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()192 void 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()202 int 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