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. safe_div(int n,int d)5int 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. bad_builtin_scope()18void 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()> bad_builtin_scope_template()29void 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 } instantiate_bad_scope_tmpl()37void 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()> func_template()44T func_template() { 45 return FN(); 46 } inject_builtins()47void inject_builtins() { 48 func_template<void *, __exception_info>(); 49 func_template<unsigned long, __exception_code>(); 50 } 51 #endif 52 use_seh_after_cxx()53void 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 use_cxx_after_seh()64void 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 use_seh_in_lambda()76void 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 use_seh_in_block()90void 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