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