xref: /llvm-project/clang/test/SemaCXX/__try.cpp (revision de57c2af61f9ac923958817a2ece16d91112f8cf)
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 Wiegley int 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 Majnemer void Except() {
637e75550fSDavid Majnemer   __try {
647e75550fSDavid Majnemer   } __except(true) {
657e75550fSDavid Majnemer   }
667e75550fSDavid Majnemer }
677e75550fSDavid Majnemer 
687e75550fSDavid Majnemer template <typename>
Finally()697e75550fSDavid Majnemer void 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 Weber void 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