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