1// RUN: %clang_cc1 -fborland-extensions -fsyntax-only -verify %s
2
3#define JOIN2(x,y) x ## y
4#define JOIN(x,y) JOIN2(x,y)
5#define TEST2(name) JOIN(name,__LINE__)
6#define TEST TEST2(test)
7typedef int DWORD;
8
9#pragma sysheader begin
10
11struct EXCEPTION_INFO{};
12
13int __exception_code();
14struct EXCEPTION_INFO* __exception_info();
15void __abnormal_termination();
16
17#define GetExceptionCode __exception_code
18#define GetExceptionInformation __exception_info
19#define AbnormalTermination __abnormal_termination
20
21#pragma sysheader end
22
23DWORD FilterExpression(int); // expected-note{{declared here}}
24DWORD FilterExceptionInformation(struct EXCEPTION_INFO*);
25
26const char * NotFilterExpression();
27
28void TEST() {
29  __try {
30    __try {
31      __try {
32      }
33      __finally{
34      }
35    }
36    __finally{
37    }
38  }
39  __finally{
40  }
41}
42
43void TEST() {
44  __try {
45
46  }
47}  // expected-error{{expected '__except' or '__finally' block}}
48
49void TEST() {
50  __except ( FilterExpression() ) { // expected-warning{{implicit declaration of function '__except' is invalid in C99}} \
51    // expected-error{{too few arguments to function call, expected 1, have 0}}
52
53  }
54}
55
56void TEST() {
57  __finally { } // expected-error{{}}
58}
59
60void TEST() {
61  __try{
62    int try_scope = 0;
63  } // TODO: expected expression is an extra error
64  __except( try_scope ? 1 : -1 ) // expected-error{{undeclared identifier 'try_scope'}} expected-error{{expected expression}}
65  {}
66}
67
68void TEST() {
69  __try {
70
71  }
72  // TODO: Why are there two errors?
73  __except( ) { // expected-error{{expected expression}} expected-error{{expected expression}}
74  }
75}
76
77void TEST() {
78  __try {
79
80  }
81  __except ( FilterExpression(GetExceptionCode()) ) {
82
83  }
84
85  __try {
86
87  }
88  __except( FilterExpression(__exception_code()) ) {
89
90  }
91
92  __try {
93
94  }
95  __except( FilterExceptionInformation(__exception_info()) ) {
96
97  }
98
99  __try {
100
101  }
102  __except(FilterExceptionInformation( GetExceptionInformation() ) ) {
103
104  }
105}
106
107void TEST() {
108  __try {
109
110  }
111  __except ( NotFilterExpression() ) { // expected-error{{filter expression type should be an integral value not 'const char *'}}
112
113  }
114}
115
116void TEST() {
117  int function_scope = 0;
118  __try {
119    int try_scope = 0;
120  }
121  __except ( FilterExpression(GetExceptionCode()) ) {
122    (void)function_scope;
123    (void)try_scope; // expected-error{{undeclared identifier}}
124  }
125}
126
127void TEST() {
128  int function_scope = 0;
129  __try {
130    int try_scope = 0;
131  }
132  __finally {
133    (void)function_scope;
134    (void)try_scope; // expected-error{{undeclared identifier}}
135  }
136}
137
138void TEST() {
139  int function_scope = 0;
140  __try {
141
142  }
143  __except( function_scope ? 1 : -1 ) {}
144}
145
146void TEST() {
147  __try {
148    (void)AbnormalTermination;  // expected-error{{only allowed in __finally block}}
149    (void)__abnormal_termination; // expected-error{{only allowed in __finally block}}
150  }
151  __except( 1 ) {
152    (void)AbnormalTermination;  // expected-error{{only allowed in __finally block}}
153    (void)__abnormal_termination; // expected-error{{only allowed in __finally block}}
154  }
155
156  __try {
157  }
158  __finally {
159    AbnormalTermination();
160    __abnormal_termination();
161  }
162}
163
164void TEST() {
165  (void)__exception_code;       // expected-error{{only allowed in __except block}}
166  (void)__exception_info;       // expected-error{{only allowed in __except filter expression}}
167  (void)__abnormal_termination; // expected-error{{only allowed in __finally block}}
168
169  (void)GetExceptionCode();     // expected-error{{only allowed in __except block}}
170  (void)GetExceptionInformation(); // expected-error{{only allowed in __except filter expression}}
171  (void)AbnormalTermination();  // expected-error{{only allowed in __finally block}}
172}
173
174void test_seh_leave_stmt() {
175  __leave; // expected-error{{'__leave' statement not in __try block}}
176
177  __try {
178    __leave;
179    __leave 4; // expected-error{{expected ';' after __leave statement}}
180  } __except(1) {
181    __leave; // expected-error{{'__leave' statement not in __try block}}
182  }
183
184  __try {
185    __leave;
186  } __finally {
187    __leave; // expected-error{{'__leave' statement not in __try block}}
188  }
189  __leave; // expected-error{{'__leave' statement not in __try block}}
190}
191
192