Clang Project

clang_source_code/test/SemaCXX/attr-noreturn.cpp
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.
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 {{control reaches end of non-void function}}
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-null
146  // 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-null
160  // pointers or derived class pointers,  so it can't determine that this
161  // 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// PR5620
169void f0() __attribute__((__noreturn__));
170void f1(void (*)());
171void f2() { f1(f0); }
172
173// Taking the address of a noreturn function
174void 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 pointers
188typedef void (* noreturn_fp)() __attribute__((noreturn));
189
190void f3(noreturn_fp); // expected-note{{candidate function}}
191
192void test_f3() {
193  f3(f0); // okay
194  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// PR12948
207
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// PR15291
233// 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 'PR15291::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 'PR15291::fptr_noreturn_t' (aka 'void (*)(int) __attribute__((noreturn))') for 1st argument}}
274  // expected-note@+1 {{candidate function not viable: no overload of 'qux' matching 'PR15291::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