xref: /aosp_15_r20/external/clang/test/SemaCXX/exceptions.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s
2*67e74705SXin Li // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++98 %s
3*67e74705SXin Li // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 %s
4*67e74705SXin Li 
5*67e74705SXin Li struct A; // expected-note 4 {{forward declaration of 'A'}}
6*67e74705SXin Li 
7*67e74705SXin Li struct Abstract { virtual void f() = 0; }; // expected-note {{unimplemented pure virtual method 'f'}}
8*67e74705SXin Li 
trys()9*67e74705SXin Li void trys() {
10*67e74705SXin Li   try {
11*67e74705SXin Li   } catch(int i) { // expected-note {{previous definition}}
12*67e74705SXin Li     int j = i;
13*67e74705SXin Li     int i; // expected-error {{redefinition of 'i'}}
14*67e74705SXin Li   } catch(float i) {
15*67e74705SXin Li   } catch(void v) { // expected-error {{cannot catch incomplete type 'void'}}
16*67e74705SXin Li   } catch(A a) { // expected-error {{cannot catch incomplete type 'A'}}
17*67e74705SXin Li   } catch(A *a) { // expected-error {{cannot catch pointer to incomplete type 'A'}}
18*67e74705SXin Li   } catch(A &a) { // expected-error {{cannot catch reference to incomplete type 'A'}}
19*67e74705SXin Li   } catch(Abstract) { // expected-error {{variable type 'Abstract' is an abstract class}}
20*67e74705SXin Li   } catch(...) {
21*67e74705SXin Li     int j = i; // expected-error {{use of undeclared identifier 'i'}}
22*67e74705SXin Li   }
23*67e74705SXin Li 
24*67e74705SXin Li   try {
25*67e74705SXin Li   } catch(...) { // expected-error {{catch-all handler must come last}}
26*67e74705SXin Li   } catch(int) {
27*67e74705SXin Li   }
28*67e74705SXin Li }
29*67e74705SXin Li 
throws()30*67e74705SXin Li void throws() {
31*67e74705SXin Li   throw;
32*67e74705SXin Li   throw 0;
33*67e74705SXin Li   throw throw; // expected-error {{cannot throw object of incomplete type 'void'}}
34*67e74705SXin Li   throw (A*)0; // expected-error {{cannot throw pointer to object of incomplete type 'A'}}
35*67e74705SXin Li }
36*67e74705SXin Li 
jumps()37*67e74705SXin Li void jumps() {
38*67e74705SXin Li l1:
39*67e74705SXin Li   goto l5;
40*67e74705SXin Li   goto l4; // expected-error {{cannot jump}}
41*67e74705SXin Li   goto l3; // expected-error {{cannot jump}}
42*67e74705SXin Li   goto l2; // expected-error {{cannot jump}}
43*67e74705SXin Li   goto l1;
44*67e74705SXin Li   try { // expected-note 4 {{jump bypasses initialization of try block}}
45*67e74705SXin Li   l2:
46*67e74705SXin Li     goto l5;
47*67e74705SXin Li     goto l4; // expected-error {{cannot jump}}
48*67e74705SXin Li     goto l3; // expected-error {{cannot jump}}
49*67e74705SXin Li     goto l2;
50*67e74705SXin Li     goto l1;
51*67e74705SXin Li   } catch(int) { // expected-note 4 {{jump bypasses initialization of catch block}}
52*67e74705SXin Li   l3:
53*67e74705SXin Li     goto l5;
54*67e74705SXin Li     goto l4; // expected-error {{cannot jump}}
55*67e74705SXin Li     goto l3;
56*67e74705SXin Li     goto l2; // expected-error {{cannot jump}}
57*67e74705SXin Li     goto l1;
58*67e74705SXin Li   } catch(...) { // expected-note 4 {{jump bypasses initialization of catch block}}
59*67e74705SXin Li   l4:
60*67e74705SXin Li     goto l5;
61*67e74705SXin Li     goto l4;
62*67e74705SXin Li     goto l3; // expected-error {{cannot jump}}
63*67e74705SXin Li     goto l2; // expected-error {{cannot jump}}
64*67e74705SXin Li     goto l1;
65*67e74705SXin Li   }
66*67e74705SXin Li l5:
67*67e74705SXin Li   goto l5;
68*67e74705SXin Li   goto l4; // expected-error {{cannot jump}}
69*67e74705SXin Li   goto l3; // expected-error {{cannot jump}}
70*67e74705SXin Li   goto l2; // expected-error {{cannot jump}}
71*67e74705SXin Li   goto l1;
72*67e74705SXin Li }
73*67e74705SXin Li 
74*67e74705SXin Li struct BadReturn {
BadReturnBadReturn75*67e74705SXin Li   BadReturn() try {
76*67e74705SXin Li   } catch(...) {
77*67e74705SXin Li     // Try to hide
78*67e74705SXin Li     try {
79*67e74705SXin Li     } catch(...) {
80*67e74705SXin Li       {
81*67e74705SXin Li         if (0)
82*67e74705SXin Li           return; // expected-error {{return in the catch of a function try block of a constructor is illegal}}
83*67e74705SXin Li       }
84*67e74705SXin Li     }
85*67e74705SXin Li   }
86*67e74705SXin Li   BadReturn(int);
87*67e74705SXin Li };
88*67e74705SXin Li 
BadReturn(int)89*67e74705SXin Li BadReturn::BadReturn(int) try {
90*67e74705SXin Li } catch(...) {
91*67e74705SXin Li   // Try to hide
92*67e74705SXin Li   try {
93*67e74705SXin Li   } catch(int) {
94*67e74705SXin Li     return; // expected-error {{return in the catch of a function try block of a constructor is illegal}}
95*67e74705SXin Li   } catch(...) {
96*67e74705SXin Li     {
97*67e74705SXin Li       if (0)
98*67e74705SXin Li         return; // expected-error {{return in the catch of a function try block of a constructor is illegal}}
99*67e74705SXin Li     }
100*67e74705SXin Li   }
101*67e74705SXin Li }
102*67e74705SXin Li 
103*67e74705SXin Li // Cannot throw an abstract type.
104*67e74705SXin Li class foo {
105*67e74705SXin Li public:
foo()106*67e74705SXin Li   foo() {}
bar()107*67e74705SXin Li   void bar () {
108*67e74705SXin Li     throw *this; // expected-error{{cannot throw an object of abstract type 'foo'}}
109*67e74705SXin Li   }
110*67e74705SXin Li   virtual void test () = 0; // expected-note{{unimplemented pure virtual method 'test'}}
111*67e74705SXin Li };
112*67e74705SXin Li 
113*67e74705SXin Li namespace PR6831 {
114*67e74705SXin Li   namespace NA { struct S; }
115*67e74705SXin Li   namespace NB { struct S; }
116*67e74705SXin Li 
f()117*67e74705SXin Li   void f() {
118*67e74705SXin Li     using namespace NA;
119*67e74705SXin Li     using namespace NB;
120*67e74705SXin Li     try {
121*67e74705SXin Li     } catch (int S) {
122*67e74705SXin Li     }
123*67e74705SXin Li   }
124*67e74705SXin Li }
125*67e74705SXin Li 
126*67e74705SXin Li namespace Decay {
127*67e74705SXin Li   struct A {
128*67e74705SXin Li     void f() throw (A[10]);
129*67e74705SXin Li   };
130*67e74705SXin Li 
131*67e74705SXin Li   template<typename T> struct B {
132*67e74705SXin Li     void f() throw (B[10]);
133*67e74705SXin Li   };
134*67e74705SXin Li   template struct B<int>;
135*67e74705SXin Li 
136*67e74705SXin Li   void f() throw (int[10], int(*)());
137*67e74705SXin Li   void f() throw (int*, int());
138*67e74705SXin Li 
139*67e74705SXin Li   template<typename T> struct C {
140*67e74705SXin Li     void f() throw (T);
141*67e74705SXin Li #if __cplusplus <= 199711L
142*67e74705SXin Li     // expected-error@-2 {{pointer to incomplete type 'Decay::E' is not allowed in exception specification}}
143*67e74705SXin Li #endif
144*67e74705SXin Li   };
145*67e74705SXin Li   struct D {
146*67e74705SXin Li     C<D[10]> c;
147*67e74705SXin Li   };
148*67e74705SXin Li   struct E;
149*67e74705SXin Li #if __cplusplus <= 199711L
150*67e74705SXin Li   // expected-note@-2 {{forward declaration of 'Decay::E'}}
151*67e74705SXin Li #endif
152*67e74705SXin Li 
153*67e74705SXin Li   C<E[10]> e;
154*67e74705SXin Li #if __cplusplus <= 199711L
155*67e74705SXin Li   // expected-note@-2 {{in instantiation of template class 'Decay::C<Decay::E [10]>' requested here}}
156*67e74705SXin Li #endif
157*67e74705SXin Li }
158*67e74705SXin Li 
159*67e74705SXin Li void rval_ref() throw (int &&); // expected-error {{rvalue reference type 'int &&' is not allowed in exception specification}}
160*67e74705SXin Li #if __cplusplus <= 199711L
161*67e74705SXin Li // expected-warning@-2 {{rvalue references are a C++11 extension}}
162*67e74705SXin Li #endif
163*67e74705SXin Li 
164*67e74705SXin Li namespace HandlerInversion {
165*67e74705SXin Li struct B {};
166*67e74705SXin Li struct D : B {};
167*67e74705SXin Li struct D2 : D {};
168*67e74705SXin Li 
f1()169*67e74705SXin Li void f1() {
170*67e74705SXin Li   try {
171*67e74705SXin Li   } catch (B &b) { // expected-note {{for type 'HandlerInversion::B &'}}
172*67e74705SXin Li   } catch (D &d) { // expected-warning {{exception of type 'HandlerInversion::D &' will be caught by earlier handler}}
173*67e74705SXin Li   }
174*67e74705SXin Li }
175*67e74705SXin Li 
f2()176*67e74705SXin Li void f2() {
177*67e74705SXin Li   try {
178*67e74705SXin Li   } catch (B *b) { // expected-note {{for type 'HandlerInversion::B *'}}
179*67e74705SXin Li   } catch (D *d) { // expected-warning {{exception of type 'HandlerInversion::D *' will be caught by earlier handler}}
180*67e74705SXin Li   }
181*67e74705SXin Li }
182*67e74705SXin Li 
f3()183*67e74705SXin Li void f3() {
184*67e74705SXin Li   try {
185*67e74705SXin Li   } catch (D &d) { // Ok
186*67e74705SXin Li   } catch (B &b) {
187*67e74705SXin Li   }
188*67e74705SXin Li }
189*67e74705SXin Li 
f4()190*67e74705SXin Li void f4() {
191*67e74705SXin Li   try {
192*67e74705SXin Li   } catch (B &b) { // Ok
193*67e74705SXin Li   }
194*67e74705SXin Li }
195*67e74705SXin Li 
f5()196*67e74705SXin Li void f5() {
197*67e74705SXin Li   try {
198*67e74705SXin Li   } catch (int) {
199*67e74705SXin Li   } catch (float) {
200*67e74705SXin Li   }
201*67e74705SXin Li }
202*67e74705SXin Li 
f6()203*67e74705SXin Li void f6() {
204*67e74705SXin Li   try {
205*67e74705SXin Li   } catch (B &b) {  // expected-note {{for type 'HandlerInversion::B &'}}
206*67e74705SXin Li   } catch (D2 &d) {  // expected-warning {{exception of type 'HandlerInversion::D2 &' will be caught by earlier handler}}
207*67e74705SXin Li   }
208*67e74705SXin Li }
209*67e74705SXin Li 
f7()210*67e74705SXin Li void f7() {
211*67e74705SXin Li   try {
212*67e74705SXin Li   } catch (B *b) { // Ok
213*67e74705SXin Li   } catch (D &d) { // Ok
214*67e74705SXin Li   }
215*67e74705SXin Li 
216*67e74705SXin Li   try {
217*67e74705SXin Li   } catch (B b) { // Ok
218*67e74705SXin Li   } catch (D *d) { // Ok
219*67e74705SXin Li   }
220*67e74705SXin Li }
221*67e74705SXin Li 
f8()222*67e74705SXin Li void f8() {
223*67e74705SXin Li   try {
224*67e74705SXin Li   } catch (const B &b) {  // expected-note {{for type 'const HandlerInversion::B &'}}
225*67e74705SXin Li   } catch (D2 &d) {  // expected-warning {{exception of type 'HandlerInversion::D2 &' will be caught by earlier handler}}
226*67e74705SXin Li   }
227*67e74705SXin Li 
228*67e74705SXin Li   try {
229*67e74705SXin Li   } catch (B &b) {  // expected-note {{for type 'HandlerInversion::B &'}}
230*67e74705SXin Li   } catch (const D2 &d) {  // expected-warning {{exception of type 'const HandlerInversion::D2 &' will be caught by earlier handler}}
231*67e74705SXin Li   }
232*67e74705SXin Li 
233*67e74705SXin Li   try {
234*67e74705SXin Li   } catch (B b) { // expected-note {{for type 'HandlerInversion::B'}}
235*67e74705SXin Li   } catch (D &d) { // expected-warning {{exception of type 'HandlerInversion::D &' will be caught by earlier handler}}
236*67e74705SXin Li   }
237*67e74705SXin Li }
238*67e74705SXin Li }
239*67e74705SXin Li 
240*67e74705SXin Li namespace ConstVolatileThrow {
241*67e74705SXin Li struct S {
SConstVolatileThrow::S242*67e74705SXin Li   S() {}         // expected-note{{candidate constructor not viable}}
243*67e74705SXin Li   S(const S &s); // expected-note{{candidate constructor not viable}}
244*67e74705SXin Li };
245*67e74705SXin Li 
246*67e74705SXin Li typedef const volatile S CVS;
247*67e74705SXin Li 
f()248*67e74705SXin Li void f() {
249*67e74705SXin Li   throw CVS(); // expected-error{{no matching constructor for initialization}}
250*67e74705SXin Li }
251*67e74705SXin Li }
252*67e74705SXin Li 
253*67e74705SXin Li namespace ConstVolatileCatch {
254*67e74705SXin Li struct S {
SConstVolatileCatch::S255*67e74705SXin Li   S() {}
256*67e74705SXin Li   S(const volatile S &s);
257*67e74705SXin Li 
258*67e74705SXin Li private:
259*67e74705SXin Li   S(const S &s); // expected-note {{declared private here}}
260*67e74705SXin Li };
261*67e74705SXin Li 
262*67e74705SXin Li void f();
263*67e74705SXin Li 
g()264*67e74705SXin Li void g() {
265*67e74705SXin Li   try {
266*67e74705SXin Li     f();
267*67e74705SXin Li   } catch (volatile S s) { // expected-error {{calling a private constructor}}
268*67e74705SXin Li   }
269*67e74705SXin Li }
270*67e74705SXin Li }
271*67e74705SXin Li 
272*67e74705SXin Li namespace PR28047 {
test1(int i)273*67e74705SXin Li void test1(int i) {
274*67e74705SXin Li   try {
275*67e74705SXin Li   } catch (int(*)[i]) { // expected-error{{cannot catch variably modified type}}
276*67e74705SXin Li   }
277*67e74705SXin Li }
test2()278*67e74705SXin Li void test2() {
279*67e74705SXin Li   int i;
280*67e74705SXin Li   try {
281*67e74705SXin Li   } catch (int(*)[i]) { // expected-error{{cannot catch variably modified type}}
282*67e74705SXin Li   }
283*67e74705SXin Li }
284*67e74705SXin Li }
285