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