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