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)
8typedef int DWORD;
9
10#pragma sysheader begin
11
12struct EXCEPTION_INFO{};
13
14unsigned long __exception_code();
15#ifdef BORLAND
16struct EXCEPTION_INFO* __exception_info();
17#endif
18int __abnormal_termination();
19
20#define GetExceptionCode __exception_code
21#define GetExceptionInformation __exception_info
22#define AbnormalTermination __abnormal_termination
23
24#pragma sysheader end
25
26DWORD FilterExpression(int); // expected-note{{declared here}}
27DWORD FilterExceptionInformation(struct EXCEPTION_INFO*);
28
29const char * NotFilterExpression();
30
31void TEST() {
32  __try {
33    __try {
34      __try {
35      }
36      __finally{
37      }
38    }
39    __finally{
40    }
41  }
42  __finally{
43  }
44}
45
46void TEST() {
47  __try {
48
49  }
50}  // expected-error{{expected '__except' or '__finally' block}}
51
52void 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
59void TEST() {
60  __finally { } // expected-error{{}}
61}
62
63void 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
71void 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
80void 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
110void 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
119void 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
130void 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
141void TEST() {
142  int function_scope = 0;
143  __try {
144
145  }
146  __except( function_scope ? 1 : -1 ) {}
147}
148
149#ifdef BORLAND
150void 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
172void 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
177void 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
185void TEST() {
186  __try {
187  } __except(1) {
188    GetExceptionCode(); // valid
189    GetExceptionInformation(); // expected-error{{only allowed in __except filter expression}}
190  }
191}
192
193void 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
211void 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
285void 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