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 Liint 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 Livoid 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 Livoid 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 Livoid 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