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