diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2024-01-24 19:17:23 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2024-04-19 21:14:13 +0000 |
| commit | a58f00ea91514a4814b96b25bcb8dc79e946edce (patch) | |
| tree | b15392e159cea54d70d2e224a6ce8e1e415b6d00 /contrib/llvm-project/libcxx/include/__exception/exception_ptr.h | |
| parent | c8734e140f632b76ff5e638afcde7258bd688d2f (diff) | |
Diffstat (limited to 'contrib/llvm-project/libcxx/include/__exception/exception_ptr.h')
| -rw-r--r-- | contrib/llvm-project/libcxx/include/__exception/exception_ptr.h | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/contrib/llvm-project/libcxx/include/__exception/exception_ptr.h b/contrib/llvm-project/libcxx/include/__exception/exception_ptr.h index 970d8196724b..53e2f718bc1b 100644 --- a/contrib/llvm-project/libcxx/include/__exception/exception_ptr.h +++ b/contrib/llvm-project/libcxx/include/__exception/exception_ptr.h @@ -9,16 +9,44 @@ #ifndef _LIBCPP___EXCEPTION_EXCEPTION_PTR_H #define _LIBCPP___EXCEPTION_EXCEPTION_PTR_H +#include <__availability> #include <__config> #include <__exception/operations.h> #include <__memory/addressof.h> +#include <__memory/construct_at.h> +#include <__type_traits/decay.h> #include <cstddef> #include <cstdlib> +#include <new> +#include <typeinfo> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +#ifndef _LIBCPP_ABI_MICROSOFT + +namespace __cxxabiv1 { + +extern "C" { +_LIBCPP_OVERRIDABLE_FUNC_VIS void* __cxa_allocate_exception(size_t) throw(); +_LIBCPP_OVERRIDABLE_FUNC_VIS void __cxa_free_exception(void*) throw(); + +struct __cxa_exception; +_LIBCPP_OVERRIDABLE_FUNC_VIS __cxa_exception* __cxa_init_primary_exception( + void*, + std::type_info*, + void( +# if defined(_WIN32) + __thiscall +# endif + *)(void*)) throw(); +} + +} // namespace __cxxabiv1 + +#endif + namespace std { // purposefully not using versioning namespace #ifndef _LIBCPP_ABI_MICROSOFT @@ -26,6 +54,11 @@ namespace std { // purposefully not using versioning namespace class _LIBCPP_EXPORTED_FROM_ABI exception_ptr { void* __ptr_; + static exception_ptr __from_native_exception_pointer(void*) _NOEXCEPT; + + template <class _Ep> + friend _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep) _NOEXCEPT; + public: _LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {} _LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {} @@ -51,11 +84,28 @@ public: template <class _Ep> _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT { # ifndef _LIBCPP_HAS_NO_EXCEPTIONS +# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION && __cplusplus >= 201103L + using _Ep2 = __decay_t<_Ep>; + + void* __ex = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ep)); + (void)__cxxabiv1::__cxa_init_primary_exception(__ex, const_cast<std::type_info*>(&typeid(_Ep)), [](void* __p) { + std::__destroy_at(static_cast<_Ep2*>(__p)); + }); + + try { + ::new (__ex) _Ep2(__e); + return exception_ptr::__from_native_exception_pointer(__ex); + } catch (...) { + __cxxabiv1::__cxa_free_exception(__ex); + return current_exception(); + } +# else try { throw __e; } catch (...) { return current_exception(); } +# endif # else ((void)__e); std::abort(); |
