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