1 | // RUN: %clang_cc1 -triple x86_64-windows -fborland-extensions -DBORLAND -fsyntax-only -verify -fblocks %s |
2 | // RUN: %clang_cc1 -triple x86_64-windows -fms-extensions -fsyntax-only -verify -fblocks %s |
3 | |
4 | #define JOIN2(x,y) x ## y |
5 | #define JOIN(x,y) JOIN2(x,y) |
6 | #define TEST2(name) JOIN(name,__LINE__) |
7 | #define TEST TEST2(test) |
8 | typedef int DWORD; |
9 | |
10 | #pragma sysheader begin |
11 | |
12 | struct EXCEPTION_INFO{}; |
13 | |
14 | unsigned long __exception_code(); |
15 | #ifdef BORLAND |
16 | struct EXCEPTION_INFO* __exception_info(); |
17 | #endif |
18 | int __abnormal_termination(); |
19 | |
20 | #define GetExceptionCode __exception_code |
21 | #define GetExceptionInformation __exception_info |
22 | #define AbnormalTermination __abnormal_termination |
23 | |
24 | #pragma sysheader end |
25 | |
26 | DWORD FilterExpression(int); // expected-note{{declared here}} |
27 | DWORD FilterExceptionInformation(struct EXCEPTION_INFO*); |
28 | |
29 | const char * NotFilterExpression(); |
30 | |
31 | void TEST() { |
32 | __try { |
33 | __try { |
34 | __try { |
35 | } |
36 | __finally{ |
37 | } |
38 | } |
39 | __finally{ |
40 | } |
41 | } |
42 | __finally{ |
43 | } |
44 | } |
45 | |
46 | void TEST() { |
47 | __try { |
48 | |
49 | } |
50 | } // expected-error{{expected '__except' or '__finally' block}} |
51 | |
52 | void TEST() { |
53 | __except ( FilterExpression() ) { // expected-warning{{implicit declaration of function '__except' is invalid in C99}} \ |
54 | // expected-error{{too few arguments to function call, expected 1, have 0}} |
55 | |
56 | } |
57 | } |
58 | |
59 | void TEST() { |
60 | __finally { } // expected-error{{}} |
61 | } |
62 | |
63 | void TEST() { |
64 | __try{ |
65 | int try_scope = 0; |
66 | } // TODO: expected expression is an extra error |
67 | __except( try_scope ? 1 : -1 ) // expected-error{{undeclared identifier 'try_scope'}} expected-error{{expected expression}} |
68 | {} |
69 | } |
70 | |
71 | void TEST() { |
72 | __try { |
73 | |
74 | } |
75 | // TODO: Why are there two errors? |
76 | __except( ) { // expected-error{{expected expression}} expected-error{{expected expression}} |
77 | } |
78 | } |
79 | |
80 | void TEST() { |
81 | __try { |
82 | |
83 | } |
84 | __except ( FilterExpression(GetExceptionCode()) ) { |
85 | |
86 | } |
87 | |
88 | __try { |
89 | |
90 | } |
91 | __except( FilterExpression(__exception_code()) ) { |
92 | |
93 | } |
94 | |
95 | __try { |
96 | |
97 | } |
98 | __except( FilterExceptionInformation(__exception_info()) ) { |
99 | |
100 | } |
101 | |
102 | __try { |
103 | |
104 | } |
105 | __except(FilterExceptionInformation( GetExceptionInformation() ) ) { |
106 | |
107 | } |
108 | } |
109 | |
110 | void TEST() { |
111 | __try { |
112 | |
113 | } |
114 | __except ( NotFilterExpression() ) { // expected-error{{filter expression type should be an integral value not 'const char *'}} |
115 | |
116 | } |
117 | } |
118 | |
119 | void TEST() { |
120 | int function_scope = 0; |
121 | __try { |
122 | int try_scope = 0; |
123 | } |
124 | __except ( FilterExpression(GetExceptionCode()) ) { |
125 | (void)function_scope; |
126 | (void)try_scope; // expected-error{{undeclared identifier}} |
127 | } |
128 | } |
129 | |
130 | void TEST() { |
131 | int function_scope = 0; |
132 | __try { |
133 | int try_scope = 0; |
134 | } |
135 | __finally { |
136 | (void)function_scope; |
137 | (void)try_scope; // expected-error{{undeclared identifier}} |
138 | } |
139 | } |
140 | |
141 | void TEST() { |
142 | int function_scope = 0; |
143 | __try { |
144 | |
145 | } |
146 | __except( function_scope ? 1 : -1 ) {} |
147 | } |
148 | |
149 | #ifdef BORLAND |
150 | void TEST() { |
151 | (void)__abnormal_termination(); // expected-error{{only allowed in __finally block}} |
152 | (void)AbnormalTermination(); // expected-error{{only allowed in __finally block}} |
153 | |
154 | __try { |
155 | (void)AbnormalTermination; // expected-error{{only allowed in __finally block}} |
156 | (void)__abnormal_termination; // expected-error{{only allowed in __finally block}} |
157 | } |
158 | __except( 1 ) { |
159 | (void)AbnormalTermination; // expected-error{{only allowed in __finally block}} |
160 | (void)__abnormal_termination; // expected-error{{only allowed in __finally block}} |
161 | } |
162 | |
163 | __try { |
164 | } |
165 | __finally { |
166 | AbnormalTermination(); |
167 | __abnormal_termination(); |
168 | } |
169 | } |
170 | #endif |
171 | |
172 | void TEST() { |
173 | (void)__exception_info(); // expected-error{{only allowed in __except filter expression}} |
174 | (void)GetExceptionInformation(); // expected-error{{only allowed in __except filter expression}} |
175 | } |
176 | |
177 | void TEST() { |
178 | #ifndef BORLAND |
179 | (void)__exception_code; // expected-error{{builtin functions must be directly called}} |
180 | #endif |
181 | (void)__exception_code(); // expected-error{{only allowed in __except block or filter expression}} |
182 | (void)GetExceptionCode(); // expected-error{{only allowed in __except block or filter expression}} |
183 | } |
184 | |
185 | void TEST() { |
186 | __try { |
187 | } __except(1) { |
188 | GetExceptionCode(); // valid |
189 | GetExceptionInformation(); // expected-error{{only allowed in __except filter expression}} |
190 | } |
191 | } |
192 | |
193 | void test_seh_leave_stmt() { |
194 | __leave; // expected-error{{'__leave' statement not in __try block}} |
195 | |
196 | __try { |
197 | __leave; |
198 | __leave 4; // expected-error{{expected ';' after __leave statement}} |
199 | } __except(1) { |
200 | __leave; // expected-error{{'__leave' statement not in __try block}} |
201 | } |
202 | |
203 | __try { |
204 | __leave; |
205 | } __finally { |
206 | __leave; // expected-error{{'__leave' statement not in __try block}} |
207 | } |
208 | __leave; // expected-error{{'__leave' statement not in __try block}} |
209 | } |
210 | |
211 | void test_jump_out_of___finally() { |
212 | while(1) { |
213 | __try { |
214 | } __finally { |
215 | continue; // expected-warning{{jump out of __finally block has undefined behavior}} |
216 | } |
217 | } |
218 | __try { |
219 | } __finally { |
220 | while (1) { |
221 | continue; |
222 | } |
223 | } |
224 | |
225 | // Check that a deep __finally containing a block with a shallow continue |
226 | // doesn't trigger the warning. |
227 | while(1) {{{{ |
228 | __try { |
229 | } __finally { |
230 | ^{ |
231 | while(1) |
232 | continue; |
233 | }(); |
234 | } |
235 | }}}} |
236 | |
237 | while(1) { |
238 | __try { |
239 | } __finally { |
240 | break; // expected-warning{{jump out of __finally block has undefined behavior}} |
241 | } |
242 | } |
243 | switch(1) { |
244 | case 1: |
245 | __try { |
246 | } __finally { |
247 | break; // expected-warning{{jump out of __finally block has undefined behavior}} |
248 | } |
249 | } |
250 | __try { |
251 | } __finally { |
252 | while (1) { |
253 | break; |
254 | } |
255 | } |
256 | |
257 | __try { |
258 | __try { |
259 | } __finally { |
260 | __leave; // expected-warning{{jump out of __finally block has undefined behavior}} |
261 | } |
262 | } __finally { |
263 | } |
264 | __try { |
265 | } __finally { |
266 | __try { |
267 | __leave; |
268 | } __finally { |
269 | } |
270 | } |
271 | |
272 | __try { |
273 | } __finally { |
274 | return; // expected-warning{{jump out of __finally block has undefined behavior}} |
275 | } |
276 | |
277 | __try { |
278 | } __finally { |
279 | ^{ |
280 | return; |
281 | }(); |
282 | } |
283 | } |
284 | |
285 | void test_typo_in_except() { |
286 | __try { |
287 | } __except(undeclared_identifier) { // expected-error {{use of undeclared identifier 'undeclared_identifier'}} expected-error {{expected expression}} |
288 | } |
289 | } |
290 | |