Index: libcxx/include/exception =================================================================== --- libcxx/include/exception +++ libcxx/include/exception @@ -141,16 +141,42 @@ #ifndef _LIBCPP_ABI_MICROSOFT +#ifndef _LIBCPP_EXCEPTION_PTR_GNU_INLINE +#define _LIBCPP_EXCEPTION_PTR_GNU_INLINE __attribute__((__gnu_inline__)) inline +#endif + class _LIBCPP_TYPE_VIS exception_ptr { void* __ptr_; + + void __incr_refcount() _NOEXCEPT; + void __decr_refcount() _NOEXCEPT; + public: _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {} _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {} - exception_ptr(const exception_ptr&) _NOEXCEPT; - exception_ptr& operator=(const exception_ptr&) _NOEXCEPT; - ~exception_ptr() _NOEXCEPT; + _LIBCPP_EXCEPTION_PTR_GNU_INLINE exception_ptr(const exception_ptr&) _NOEXCEPT; + _LIBCPP_EXCEPTION_PTR_GNU_INLINE exception_ptr& operator=(const exception_ptr&) _NOEXCEPT; + _LIBCPP_EXCEPTION_PTR_GNU_INLINE ~exception_ptr() _NOEXCEPT; + + exception_ptr(exception_ptr&& __rhs) _NOEXCEPT : __ptr_(__rhs.__ptr_) { + __rhs.__ptr_ = nullptr; + } + + exception_ptr& operator=(exception_ptr&& __rhs) _NOEXCEPT { + if (__ptr_ != nullptr) + __decr_refcount(); + __ptr_ = __rhs.__ptr_; + __rhs.__ptr_ = nullptr; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY void swap(exception_ptr& __rhs) _NOEXCEPT { + void *__tmp = __ptr_; + __ptr_ = __rhs.__ptr_; + __rhs.__ptr_ = __tmp; + } _LIBCPP_INLINE_VISIBILITY explicit operator bool() const _NOEXCEPT {return __ptr_ != nullptr;} @@ -167,6 +193,34 @@ friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); }; +_LIBCPP_EXCEPTION_PTR_GNU_INLINE +exception_ptr::exception_ptr(const exception_ptr& __rhs) _NOEXCEPT : __ptr_(__rhs.__ptr_) { + if (__rhs.__ptr_ != nullptr) + __incr_refcount(); +} + +_LIBCPP_EXCEPTION_PTR_GNU_INLINE +exception_ptr& exception_ptr::operator=(const exception_ptr& __rhs) _NOEXCEPT { + if (__ptr_ != __rhs.__ptr_) { + if (__ptr_ != nullptr) + __decr_refcount(); + __ptr_ = __rhs.__ptr_; + if (__ptr_ != nullptr) + __incr_refcount(); + } + return *this; +} + +_LIBCPP_EXCEPTION_PTR_GNU_INLINE +exception_ptr::~exception_ptr() _NOEXCEPT { + if (__ptr_ != nullptr) + __decr_refcount(); +} + +inline _LIBCPP_INLINE_VISIBILITY void +swap(exception_ptr& __lhs, exception_ptr& __rhs) _NOEXCEPT +{ __lhs.swap(__rhs); } + template _LIBCPP_INLINE_VISIBILITY exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT Index: libcxx/src/exception.cpp =================================================================== --- libcxx/src/exception.cpp +++ libcxx/src/exception.cpp @@ -6,7 +6,11 @@ // //===----------------------------------------------------------------------===// +#if !defined(_LIBCPP_ABI_MICROSOFT) && !defined(__GLIBCXX__) +#define _LIBCPP_EXCEPTION_PTR_GNU_INLINE /*empty*/ +#endif #include + #include #include Index: libcxx/src/support/runtime/exception_pointer_cxxabi.ipp =================================================================== --- libcxx/src/support/runtime/exception_pointer_cxxabi.ipp +++ libcxx/src/support/runtime/exception_pointer_cxxabi.ipp @@ -13,27 +13,15 @@ namespace std { -exception_ptr::~exception_ptr() noexcept { +void exception_ptr::__decr_refcount() noexcept { __cxa_decrement_exception_refcount(__ptr_); } -exception_ptr::exception_ptr(const exception_ptr& other) noexcept - : __ptr_(other.__ptr_) +void exception_ptr::__incr_refcount() noexcept { __cxa_increment_exception_refcount(__ptr_); } -exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept -{ - if (__ptr_ != other.__ptr_) - { - __cxa_increment_exception_refcount(other.__ptr_); - __cxa_decrement_exception_refcount(__ptr_); - __ptr_ = other.__ptr_; - } - return *this; -} - nested_exception::nested_exception() noexcept : __ptr_(current_exception()) { Index: libcxx/src/support/runtime/exception_pointer_unimplemented.ipp =================================================================== --- libcxx/src/support/runtime/exception_pointer_unimplemented.ipp +++ libcxx/src/support/runtime/exception_pointer_unimplemented.ipp @@ -12,22 +12,14 @@ namespace std { -exception_ptr::~exception_ptr() noexcept +void exception_ptr::__decr_refcount() noexcept { # warning exception_ptr not yet implemented fprintf(stderr, "exception_ptr not yet implemented\n"); ::abort(); } -exception_ptr::exception_ptr(const exception_ptr& other) noexcept - : __ptr_(other.__ptr_) -{ -# warning exception_ptr not yet implemented - fprintf(stderr, "exception_ptr not yet implemented\n"); - ::abort(); -} - -exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept +void exception_ptr::__incr_refcount() noexcept { # warning exception_ptr not yet implemented fprintf(stderr, "exception_ptr not yet implemented\n");