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