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 
TEST()31 void TEST() {
32   __try {
33     __try {
34       __try {
35       }
36       __finally{
37       }
38     }
39     __finally{
40     }
41   }
42   __finally{
43   }
44 }
45 
TEST()46 void TEST() {
47   __try {
48 
49   }
50 }  // expected-error{{expected '__except' or '__finally' block}}
51 
TEST()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 
TEST()59 void TEST() {
60   __finally { } // expected-error{{}}
61 }
62 
TEST()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 
TEST()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 
TEST()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 
TEST()110 void TEST() {
111   __try {
112 
113   }
114   __except ( NotFilterExpression() ) { // expected-error{{filter expression has non-integral type 'const char *'}}
115 
116   }
117 }
118 
TEST()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 
TEST()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 
TEST()141 void TEST() {
142   int function_scope = 0;
143   __try {
144 
145   }
146   __except( function_scope ? 1 : -1 ) {}
147 }
148 
149 #ifdef BORLAND
TEST()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 
TEST()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 
TEST()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 
TEST()185 void TEST() {
186   __try {
187   } __except(1) {
188     GetExceptionCode(); // valid
189     GetExceptionInformation(); // expected-error{{only allowed in __except filter expression}}
190   }
191 }
192 
test_seh_leave_stmt()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 
test_jump_out_of___finally()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 
test_typo_in_except()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