Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -std=c++03 -fblocks -triple x86_64-windows-msvc -fms-extensions -fsyntax-only -fexceptions -fcxx-exceptions -verify %s
      2 // RUN: %clang_cc1 -std=c++11 -fblocks -triple x86_64-windows-msvc -fms-extensions -fsyntax-only -fexceptions -fcxx-exceptions -verify %s
      3 
      4 // Basic usage should work.
      5 int safe_div(int n, int d) {
      6   int r;
      7   __try {
      8     r = n / d;
      9   } __except(_exception_code() == 0xC0000094) {
     10     r = 0;
     11   }
     12   return r;
     13 }
     14 
     15 void might_crash();
     16 
     17 // Diagnose obvious builtin mis-usage.
     18 void bad_builtin_scope() {
     19   __try {
     20     might_crash();
     21   } __except(1) {
     22   }
     23   _exception_code(); // expected-error {{'_exception_code' only allowed in __except block or filter expression}}
     24   _exception_info(); // expected-error {{'_exception_info' only allowed in __except filter expression}}
     25 }
     26 
     27 // Diagnose obvious builtin misusage in a template.
     28 template <void FN()>
     29 void bad_builtin_scope_template() {
     30   __try {
     31     FN();
     32   } __except(1) {
     33   }
     34   _exception_code(); // expected-error {{'_exception_code' only allowed in __except block or filter expression}}
     35   _exception_info(); // expected-error {{'_exception_info' only allowed in __except filter expression}}
     36 }
     37 void instantiate_bad_scope_tmpl() {
     38   bad_builtin_scope_template<might_crash>();
     39 }
     40 
     41 #if __cplusplus < 201103L
     42 // FIXME: Diagnose this case. For now we produce undef in codegen.
     43 template <typename T, T FN()>
     44 T func_template() {
     45   return FN();
     46 }
     47 void inject_builtins() {
     48   func_template<void *, __exception_info>();
     49   func_template<unsigned long, __exception_code>();
     50 }
     51 #endif
     52 
     53 void use_seh_after_cxx() {
     54   try { // expected-note {{conflicting 'try' here}}
     55     might_crash();
     56   } catch (int) {
     57   }
     58   __try { // expected-error {{cannot use C++ 'try' in the same function as SEH '__try'}}
     59     might_crash();
     60   } __except(1) {
     61   }
     62 }
     63 
     64 void use_cxx_after_seh() {
     65   __try { // expected-note {{conflicting '__try' here}}
     66     might_crash();
     67   } __except(1) {
     68   }
     69   try { // expected-error {{cannot use C++ 'try' in the same function as SEH '__try'}}
     70     might_crash();
     71   } catch (int) {
     72   }
     73 }
     74 
     75 #if __cplusplus >= 201103L
     76 void use_seh_in_lambda() {
     77   ([]() {
     78     __try {
     79       might_crash();
     80     } __except(1) {
     81     }
     82   })();
     83   try {
     84     might_crash();
     85   } catch (int) {
     86   }
     87 }
     88 #endif
     89 
     90 void use_seh_in_block() {
     91   void (^b)() = ^{
     92     __try { // expected-error {{cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls}}
     93       might_crash();
     94     } __except(1) {
     95     }
     96   };
     97   try {
     98     b();
     99   } catch (int) {
    100   }
    101 }
    102 
    103 void (^use_seh_in_global_block)() = ^{
    104   __try { // expected-error {{cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls}}
    105     might_crash();
    106   } __except(1) {
    107   }
    108 };
    109 
    110 void (^use_cxx_in_global_block)() = ^{
    111   try {
    112     might_crash();
    113   } catch(int) {
    114   }
    115 };
    116