| // RUN: %clang_cc1 -triple x86_64-windows -fborland-extensions -DBORLAND -fsyntax-only -verify -fblocks %s |
| // RUN: %clang_cc1 -triple x86_64-windows -fms-extensions -fsyntax-only -verify -fblocks %s |
| |
| #define JOIN2(x,y) x ## y |
| #define JOIN(x,y) JOIN2(x,y) |
| #define TEST2(name) JOIN(name,__LINE__) |
| #define TEST TEST2(test) |
| typedef int DWORD; |
| |
| #pragma sysheader begin |
| |
| struct EXCEPTION_INFO{}; |
| |
| unsigned long __exception_code(); |
| #ifdef BORLAND |
| struct EXCEPTION_INFO* __exception_info(); |
| #endif |
| int __abnormal_termination(); |
| |
| #define GetExceptionCode __exception_code |
| #define GetExceptionInformation __exception_info |
| #define AbnormalTermination __abnormal_termination |
| |
| #pragma sysheader end |
| |
| DWORD FilterExpression(int); // expected-note{{declared here}} |
| DWORD FilterExceptionInformation(struct EXCEPTION_INFO*); |
| |
| const char * NotFilterExpression(); |
| |
| void TEST() { |
| __try { |
| __try { |
| __try { |
| } |
| __finally{ |
| } |
| } |
| __finally{ |
| } |
| } |
| __finally{ |
| } |
| } |
| |
| void TEST() { |
| __try { |
| |
| } |
| } // expected-error{{expected '__except' or '__finally' block}} |
| |
| void TEST() { |
| __except ( FilterExpression() ) { // expected-warning{{implicit declaration of function '__except' is invalid in C99}} \ |
| // expected-error{{too few arguments to function call, expected 1, have 0}} |
| |
| } |
| } |
| |
| void TEST() { |
| __finally { } // expected-error{{}} |
| } |
| |
| void TEST() { |
| __try{ |
| int try_scope = 0; |
| } // TODO: expected expression is an extra error |
| __except( try_scope ? 1 : -1 ) // expected-error{{undeclared identifier 'try_scope'}} expected-error{{expected expression}} |
| {} |
| } |
| |
| void TEST() { |
| __try { |
| |
| } |
| // TODO: Why are there two errors? |
| __except( ) { // expected-error{{expected expression}} expected-error{{expected expression}} |
| } |
| } |
| |
| void TEST() { |
| __try { |
| |
| } |
| __except ( FilterExpression(GetExceptionCode()) ) { |
| |
| } |
| |
| __try { |
| |
| } |
| __except( FilterExpression(__exception_code()) ) { |
| |
| } |
| |
| __try { |
| |
| } |
| __except( FilterExceptionInformation(__exception_info()) ) { |
| |
| } |
| |
| __try { |
| |
| } |
| __except(FilterExceptionInformation( GetExceptionInformation() ) ) { |
| |
| } |
| } |
| |
| void TEST() { |
| __try { |
| |
| } |
| __except ( NotFilterExpression() ) { // expected-error{{filter expression has non-integral type 'const char *'}} |
| |
| } |
| } |
| |
| void TEST() { |
| int function_scope = 0; |
| __try { |
| int try_scope = 0; |
| } |
| __except ( FilterExpression(GetExceptionCode()) ) { |
| (void)function_scope; |
| (void)try_scope; // expected-error{{undeclared identifier}} |
| } |
| } |
| |
| void TEST() { |
| int function_scope = 0; |
| __try { |
| int try_scope = 0; |
| } |
| __finally { |
| (void)function_scope; |
| (void)try_scope; // expected-error{{undeclared identifier}} |
| } |
| } |
| |
| void TEST() { |
| int function_scope = 0; |
| __try { |
| |
| } |
| __except( function_scope ? 1 : -1 ) {} |
| } |
| |
| #ifdef BORLAND |
| void TEST() { |
| (void)__abnormal_termination(); // expected-error{{only allowed in __finally block}} |
| (void)AbnormalTermination(); // expected-error{{only allowed in __finally block}} |
| |
| __try { |
| (void)AbnormalTermination; // expected-error{{only allowed in __finally block}} |
| (void)__abnormal_termination; // expected-error{{only allowed in __finally block}} |
| } |
| __except( 1 ) { |
| (void)AbnormalTermination; // expected-error{{only allowed in __finally block}} |
| (void)__abnormal_termination; // expected-error{{only allowed in __finally block}} |
| } |
| |
| __try { |
| } |
| __finally { |
| AbnormalTermination(); |
| __abnormal_termination(); |
| } |
| } |
| #endif |
| |
| void TEST() { |
| (void)__exception_info(); // expected-error{{only allowed in __except filter expression}} |
| (void)GetExceptionInformation(); // expected-error{{only allowed in __except filter expression}} |
| } |
| |
| void TEST() { |
| #ifndef BORLAND |
| (void)__exception_code; // expected-error{{builtin functions must be directly called}} |
| #endif |
| (void)__exception_code(); // expected-error{{only allowed in __except block or filter expression}} |
| (void)GetExceptionCode(); // expected-error{{only allowed in __except block or filter expression}} |
| } |
| |
| void TEST() { |
| __try { |
| } __except(1) { |
| GetExceptionCode(); // valid |
| GetExceptionInformation(); // expected-error{{only allowed in __except filter expression}} |
| } |
| } |
| |
| void test_seh_leave_stmt() { |
| __leave; // expected-error{{'__leave' statement not in __try block}} |
| |
| __try { |
| __leave; |
| __leave 4; // expected-error{{expected ';' after __leave statement}} |
| } __except(1) { |
| __leave; // expected-error{{'__leave' statement not in __try block}} |
| } |
| |
| __try { |
| __leave; |
| } __finally { |
| __leave; // expected-error{{'__leave' statement not in __try block}} |
| } |
| __leave; // expected-error{{'__leave' statement not in __try block}} |
| } |
| |
| void test_jump_out_of___finally() { |
| while(1) { |
| __try { |
| } __finally { |
| continue; // expected-warning{{jump out of __finally block has undefined behavior}} |
| } |
| } |
| __try { |
| } __finally { |
| while (1) { |
| continue; |
| } |
| } |
| |
| // Check that a deep __finally containing a block with a shallow continue |
| // doesn't trigger the warning. |
| while(1) {{{{ |
| __try { |
| } __finally { |
| ^{ |
| while(1) |
| continue; |
| }(); |
| } |
| }}}} |
| |
| while(1) { |
| __try { |
| } __finally { |
| break; // expected-warning{{jump out of __finally block has undefined behavior}} |
| } |
| } |
| switch(1) { |
| case 1: |
| __try { |
| } __finally { |
| break; // expected-warning{{jump out of __finally block has undefined behavior}} |
| } |
| } |
| __try { |
| } __finally { |
| while (1) { |
| break; |
| } |
| } |
| |
| __try { |
| __try { |
| } __finally { |
| __leave; // expected-warning{{jump out of __finally block has undefined behavior}} |
| } |
| } __finally { |
| } |
| __try { |
| } __finally { |
| __try { |
| __leave; |
| } __finally { |
| } |
| } |
| |
| __try { |
| } __finally { |
| return; // expected-warning{{jump out of __finally block has undefined behavior}} |
| } |
| |
| __try { |
| } __finally { |
| ^{ |
| return; |
| }(); |
| } |
| } |
| |
| void test_typo_in_except() { |
| __try { |
| } __except(undeclared_identifier) { // expected-error {{use of undeclared identifier 'undeclared_identifier'}} expected-error {{expected expression}} |
| } |
| } |