summaryrefslogtreecommitdiffstats
path: root/contrib/libc++/src/exception.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libc++/src/exception.cpp')
-rw-r--r--contrib/libc++/src/exception.cpp121
1 files changed, 101 insertions, 20 deletions
diff --git a/contrib/libc++/src/exception.cpp b/contrib/libc++/src/exception.cpp
index 1d2f6b2..3ce6f2e 100644
--- a/contrib/libc++/src/exception.cpp
+++ b/contrib/libc++/src/exception.cpp
@@ -7,8 +7,10 @@
//
//===----------------------------------------------------------------------===//
#include <stdlib.h>
+#include <stdio.h>
#include "exception"
+#include "new"
#ifndef __has_include
#define __has_include(inc) 0
@@ -22,7 +24,7 @@
#ifndef _LIBCPPABI_VERSION
using namespace __cxxabiapple;
// On Darwin, there are two STL shared libraries and a lower level ABI
- // shared libray. The globals holding the current terminate handler and
+ // shared library. The globals holding the current terminate handler and
// current unexpected handler are in the ABI library.
#define __terminate_handler __cxxabiapple::__cxa_terminate_handler
#define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler
@@ -77,7 +79,7 @@ get_terminate() _NOEXCEPT
return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0);
}
-#ifndef EMSCRIPTEN // We provide this in JS
+#ifndef __EMSCRIPTEN__ // We provide this in JS
_LIBCPP_NORETURN
void
terminate() _NOEXCEPT
@@ -88,31 +90,39 @@ terminate() _NOEXCEPT
#endif // _LIBCPP_NO_EXCEPTIONS
(*get_terminate())();
// handler should not return
- ::abort ();
+ printf("terminate_handler unexpectedly returned\n");
+ ::abort();
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
// handler should not throw exception
- ::abort ();
+ printf("terminate_handler unexpectedly threw an exception\n");
+ ::abort();
}
#endif // _LIBCPP_NO_EXCEPTIONS
}
-#endif // !EMSCRIPTEN
+#endif // !__EMSCRIPTEN__
#endif // !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)
-#if !defined(LIBCXXRT) && !defined(__GLIBCXX__) && !defined(EMSCRIPTEN)
+#if !defined(LIBCXXRT) && !defined(__GLIBCXX__) && !defined(__EMSCRIPTEN__)
bool uncaught_exception() _NOEXCEPT
{
#if defined(__APPLE__) || defined(_LIBCPPABI_VERSION)
// on Darwin, there is a helper function so __cxa_get_globals is private
return __cxa_uncaught_exception();
#else // __APPLE__
- #warning uncaught_exception not yet implemented
+# if defined(_MSC_VER) && ! defined(__clang__)
+ _LIBCPP_WARNING("uncaught_exception not yet implemented")
+# else
+# warning uncaught_exception not yet implemented
+# endif
+ printf("uncaught_exception not yet implemented\n");
::abort();
#endif // __APPLE__
}
+
#ifndef _LIBCPPABI_VERSION
exception::~exception() _NOEXCEPT
@@ -139,15 +149,50 @@ const char* bad_exception::what() const _NOEXCEPT
#endif
+#if defined(__GLIBCXX__)
+
+// libsupc++ does not implement the dependent EH ABI and the functionality
+// it uses to implement std::exception_ptr (which it declares as an alias of
+// std::__exception_ptr::exception_ptr) is not directly exported to clients. So
+// we have little choice but to hijack std::__exception_ptr::exception_ptr's
+// (which fortunately has the same layout as our std::exception_ptr) copy
+// constructor, assignment operator and destructor (which are part of its
+// stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr)
+// function.
+
+namespace __exception_ptr
+{
+
+struct exception_ptr
+{
+ void* __ptr_;
+
+ exception_ptr(const exception_ptr&) _NOEXCEPT;
+ exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
+ ~exception_ptr() _NOEXCEPT;
+};
+
+}
+
+_LIBCPP_NORETURN void rethrow_exception(__exception_ptr::exception_ptr);
+
+#endif
exception_ptr::~exception_ptr() _NOEXCEPT
{
#if HAVE_DEPENDENT_EH_ABI
__cxa_decrement_exception_refcount(__ptr_);
+#elif defined(__GLIBCXX__)
+ reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr();
#else
- #warning exception_ptr not yet implemented
+# if defined(_MSC_VER) && ! defined(__clang__)
+ _LIBCPP_WARNING("exception_ptr not yet implemented")
+# else
+# warning exception_ptr not yet implemented
+# endif
+ printf("exception_ptr not yet implemented\n");
::abort();
-#endif // __APPLE__
+#endif
}
exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
@@ -155,10 +200,18 @@ exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
{
#if HAVE_DEPENDENT_EH_ABI
__cxa_increment_exception_refcount(__ptr_);
+#elif defined(__GLIBCXX__)
+ new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr(
+ reinterpret_cast<const __exception_ptr::exception_ptr&>(other));
#else
- #warning exception_ptr not yet implemented
+# if defined(_MSC_VER) && ! defined(__clang__)
+ _LIBCPP_WARNING("exception_ptr not yet implemented")
+# else
+# warning exception_ptr not yet implemented
+# endif
+ printf("exception_ptr not yet implemented\n");
::abort();
-#endif // __APPLE__
+#endif
}
exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
@@ -171,10 +224,19 @@ exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
__ptr_ = other.__ptr_;
}
return *this;
-#else // __APPLE__
- #warning exception_ptr not yet implemented
+#elif defined(__GLIBCXX__)
+ *reinterpret_cast<__exception_ptr::exception_ptr*>(this) =
+ reinterpret_cast<const __exception_ptr::exception_ptr&>(other);
+ return *this;
+#else
+# if defined(_MSC_VER) && ! defined(__clang__)
+ _LIBCPP_WARNING("exception_ptr not yet implemented")
+# else
+# warning exception_ptr not yet implemented
+# endif
+ printf("exception_ptr not yet implemented\n");
::abort();
-#endif // __APPLE__
+#endif
}
nested_exception::nested_exception() _NOEXCEPT
@@ -182,10 +244,14 @@ nested_exception::nested_exception() _NOEXCEPT
{
}
+#if !defined(__GLIBCXX__)
+
nested_exception::~nested_exception() _NOEXCEPT
{
}
+#endif
+
_LIBCPP_NORETURN
void
nested_exception::rethrow_nested() const
@@ -195,6 +261,7 @@ nested_exception::rethrow_nested() const
rethrow_exception(__ptr_);
}
+#if !defined(__GLIBCXX__)
exception_ptr current_exception() _NOEXCEPT
{
@@ -205,12 +272,19 @@ exception_ptr current_exception() _NOEXCEPT
exception_ptr ptr;
ptr.__ptr_ = __cxa_current_primary_exception();
return ptr;
-#else // __APPLE__
- #warning exception_ptr not yet implemented
+#else
+# if defined(_MSC_VER) && ! defined(__clang__)
+ _LIBCPP_WARNING( "exception_ptr not yet implemented" )
+# else
+# warning exception_ptr not yet implemented
+# endif
+ printf("exception_ptr not yet implemented\n");
::abort();
-#endif // __APPLE__
+#endif
}
+#endif // !__GLIBCXX__
+
_LIBCPP_NORETURN
void rethrow_exception(exception_ptr p)
{
@@ -218,9 +292,16 @@ void rethrow_exception(exception_ptr p)
__cxa_rethrow_primary_exception(p.__ptr_);
// if p.__ptr_ is NULL, above returns so we terminate
terminate();
-#else // __APPLE__
- #warning exception_ptr not yet implemented
+#elif defined(__GLIBCXX__)
+ rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p));
+#else
+# if defined(_MSC_VER) && ! defined(__clang__)
+ _LIBCPP_WARNING("exception_ptr not yet implemented")
+# else
+# warning exception_ptr not yet implemented
+# endif
+ printf("exception_ptr not yet implemented\n");
::abort();
-#endif // __APPLE__
+#endif
}
} // std
OpenPOWER on IntegriCloud