Home | History | Annotate | Download | only in Sema
      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