1*de57c2afSReid Kleckner // RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify -fborland-extensions -fcxx-exceptions %s 21c0675e1SJohn Wiegley 31c0675e1SJohn Wiegley // This test is from http://docwiki.embarcadero.com/RADStudio/en/Try 41c0675e1SJohn Wiegley 51c0675e1SJohn Wiegley int puts(const char *); 61c0675e1SJohn Wiegley 71c0675e1SJohn Wiegley template<typename T> 81c0675e1SJohn Wiegley int printf(const char *, T); 91c0675e1SJohn Wiegley 101c0675e1SJohn Wiegley const char * strdup(const char *); 111c0675e1SJohn Wiegley 121c0675e1SJohn Wiegley void free(const void *); 131c0675e1SJohn Wiegley 141c0675e1SJohn Wiegley #define EXCEPTION_EXECUTE_HANDLER 1 151c0675e1SJohn Wiegley 161c0675e1SJohn Wiegley class Exception 171c0675e1SJohn Wiegley { 181c0675e1SJohn Wiegley public: Exception(const char * s="Unknown")191c0675e1SJohn Wiegley Exception(const char* s = "Unknown"){what = strdup(s); } Exception(const Exception & e)201c0675e1SJohn Wiegley Exception(const Exception& e ){what = strdup(e.what); } ~Exception()211c0675e1SJohn Wiegley ~Exception() {free(what); } msg() const221c0675e1SJohn Wiegley const char* msg() const {return what; } 231c0675e1SJohn Wiegley private: 241c0675e1SJohn Wiegley const char* what; 251c0675e1SJohn Wiegley }; 261c0675e1SJohn Wiegley main()271c0675e1SJohn Wiegleyint main() 281c0675e1SJohn Wiegley { 291c0675e1SJohn Wiegley float e, f, g; 301c0675e1SJohn Wiegley try 311c0675e1SJohn Wiegley { 321c0675e1SJohn Wiegley try 331c0675e1SJohn Wiegley { 341c0675e1SJohn Wiegley f = 1.0; 351c0675e1SJohn Wiegley g = 0.0; 361c0675e1SJohn Wiegley try 371c0675e1SJohn Wiegley { 381c0675e1SJohn Wiegley puts("Another exception:"); 391c0675e1SJohn Wiegley 401c0675e1SJohn Wiegley e = f / g; 411c0675e1SJohn Wiegley } 421c0675e1SJohn Wiegley __except(EXCEPTION_EXECUTE_HANDLER) 431c0675e1SJohn Wiegley { 441c0675e1SJohn Wiegley puts("Caught a C-based exception."); 451c0675e1SJohn Wiegley throw(Exception("Hardware error: Divide by 0")); 461c0675e1SJohn Wiegley } 471c0675e1SJohn Wiegley } 481c0675e1SJohn Wiegley catch(const Exception& e) 491c0675e1SJohn Wiegley { 501c0675e1SJohn Wiegley printf("Caught C++ Exception: %s :\n", e.msg()); 511c0675e1SJohn Wiegley } 521c0675e1SJohn Wiegley } 531c0675e1SJohn Wiegley __finally 541c0675e1SJohn Wiegley { 551c0675e1SJohn Wiegley puts("C++ allows __finally too!"); 561c0675e1SJohn Wiegley } 571c0675e1SJohn Wiegley return e; 581c0675e1SJohn Wiegley } 597e75550fSDavid Majnemer 607e75550fSDavid Majnemer namespace PR17584 { 617e75550fSDavid Majnemer template <typename> Except()627e75550fSDavid Majnemervoid Except() { 637e75550fSDavid Majnemer __try { 647e75550fSDavid Majnemer } __except(true) { 657e75550fSDavid Majnemer } 667e75550fSDavid Majnemer } 677e75550fSDavid Majnemer 687e75550fSDavid Majnemer template <typename> Finally()697e75550fSDavid Majnemervoid Finally() { 707e75550fSDavid Majnemer __try { 717e75550fSDavid Majnemer } __finally { 727e75550fSDavid Majnemer } 737e75550fSDavid Majnemer } 747e75550fSDavid Majnemer 757e75550fSDavid Majnemer template void Except<void>(); 767e75550fSDavid Majnemer template void Finally<void>(); 777e75550fSDavid Majnemer 787e75550fSDavid Majnemer } 79c7d05964SNico Weber test___leave()80c7d05964SNico Webervoid test___leave() { 81c7d05964SNico Weber // Most tests are in __try.c. 82c7d05964SNico Weber 83c7d05964SNico Weber // Clang accepts try with __finally. MSVC doesn't. (Maybe a Borland thing?) 84c7d05964SNico Weber // __leave in mixed blocks isn't supported. 85c7d05964SNico Weber try { 86eb61d4d7SNico Weber __leave; // expected-error{{'__leave' statement not in __try block}} 87c7d05964SNico Weber } __finally { 88c7d05964SNico Weber } 89c7d05964SNico Weber } 90