xref: /aosp_15_r20/external/clang/test/SemaCXX/__try.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify -fborland-extensions -fcxx-exceptions %s
2*67e74705SXin Li 
3*67e74705SXin Li // This test is from http://docwiki.embarcadero.com/RADStudio/en/Try
4*67e74705SXin Li 
5*67e74705SXin Li int puts(const char *);
6*67e74705SXin Li 
7*67e74705SXin Li template<typename T>
8*67e74705SXin Li int printf(const char *, T);
9*67e74705SXin Li 
10*67e74705SXin Li const char * strdup(const char *);
11*67e74705SXin Li 
12*67e74705SXin Li void free(const void *);
13*67e74705SXin Li 
14*67e74705SXin Li #define EXCEPTION_EXECUTE_HANDLER 1
15*67e74705SXin Li 
16*67e74705SXin Li class Exception
17*67e74705SXin Li {
18*67e74705SXin Li public:
Exception(const char * s="Unknown")19*67e74705SXin Li   Exception(const char* s = "Unknown"){what = strdup(s);      }
Exception(const Exception & e)20*67e74705SXin Li   Exception(const Exception& e ){what = strdup(e.what); }
~Exception()21*67e74705SXin Li   ~Exception()                   {free(what);         }
msg() const22*67e74705SXin Li   const char* msg() const             {return what;           }
23*67e74705SXin Li private:
24*67e74705SXin Li   const char* what;
25*67e74705SXin Li };
26*67e74705SXin Li 
main()27*67e74705SXin Li int main()
28*67e74705SXin Li {
29*67e74705SXin Li   float e, f, g;
30*67e74705SXin Li   try
31*67e74705SXin Li   {
32*67e74705SXin Li     try
33*67e74705SXin Li     {
34*67e74705SXin Li       f = 1.0;
35*67e74705SXin Li       g = 0.0;
36*67e74705SXin Li       try
37*67e74705SXin Li       {
38*67e74705SXin Li         puts("Another exception:");
39*67e74705SXin Li 
40*67e74705SXin Li         e = f / g;
41*67e74705SXin Li       }
42*67e74705SXin Li       __except(EXCEPTION_EXECUTE_HANDLER)
43*67e74705SXin Li       {
44*67e74705SXin Li         puts("Caught a C-based exception.");
45*67e74705SXin Li         throw(Exception("Hardware error: Divide by 0"));
46*67e74705SXin Li       }
47*67e74705SXin Li     }
48*67e74705SXin Li     catch(const Exception& e)
49*67e74705SXin Li     {
50*67e74705SXin Li       printf("Caught C++ Exception: %s :\n", e.msg());
51*67e74705SXin Li     }
52*67e74705SXin Li   }
53*67e74705SXin Li   __finally
54*67e74705SXin Li   {
55*67e74705SXin Li     puts("C++ allows __finally too!");
56*67e74705SXin Li   }
57*67e74705SXin Li   return e;
58*67e74705SXin Li }
59*67e74705SXin Li 
60*67e74705SXin Li namespace PR17584 {
61*67e74705SXin Li template <typename>
Except()62*67e74705SXin Li void Except() {
63*67e74705SXin Li   __try {
64*67e74705SXin Li   } __except(true) {
65*67e74705SXin Li   }
66*67e74705SXin Li }
67*67e74705SXin Li 
68*67e74705SXin Li template <typename>
Finally()69*67e74705SXin Li void Finally() {
70*67e74705SXin Li   __try {
71*67e74705SXin Li   } __finally {
72*67e74705SXin Li   }
73*67e74705SXin Li }
74*67e74705SXin Li 
75*67e74705SXin Li template void Except<void>();
76*67e74705SXin Li template void Finally<void>();
77*67e74705SXin Li 
78*67e74705SXin Li }
79*67e74705SXin Li 
test___leave()80*67e74705SXin Li void test___leave() {
81*67e74705SXin Li   // Most tests are in __try.c.
82*67e74705SXin Li 
83*67e74705SXin Li   // Clang accepts try with __finally. MSVC doesn't. (Maybe a Borland thing?)
84*67e74705SXin Li   // __leave in mixed blocks isn't supported.
85*67e74705SXin Li   try {
86*67e74705SXin Li     __leave; // expected-error{{'__leave' statement not in __try block}}
87*67e74705SXin Li   } __finally {
88*67e74705SXin Li   }
89*67e74705SXin Li }
90