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 | |