Skip to content
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions libcxx/docs/ReleaseNotes/22.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ Improvements and New Features
iterators, resulting in a performance improvement for ``std::deque<short>`` and
``std::join_view<vector<vector<short>>>`` iterators.

- ``std::exception_ptr`` was optimized, allowing the compiler to generate better code especially for empty
``std::exception_ptr`` values.

Deprecations and Removals
-------------------------

Expand Down
51 changes: 32 additions & 19 deletions libcxx/include/__exception/exception_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,13 @@
#include <__memory/construct_at.h>
#include <__type_traits/decay.h>
#include <__type_traits/is_pointer.h>
#include <__utility/move.h>
#include <__utility/swap.h>
#include <__verbose_abort>
#include <typeinfo>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

#ifndef _LIBCPP_ABI_MICROSOFT

# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
Expand Down Expand Up @@ -63,11 +58,12 @@ _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD

#ifndef _LIBCPP_ABI_MICROSOFT

inline _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _NOEXCEPT;

class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
void* __ptr_;

static void __increment_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void*) _NOEXCEPT;
static void __decrement_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void*) _NOEXCEPT;

static exception_ptr __from_native_exception_pointer(void*) _NOEXCEPT;

template <class _Ep>
Expand All @@ -82,17 +78,42 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
_LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {}
_LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}

// These symbols are still exported from the library to prevent ABI breakage.
# ifdef _LIBCPP_BUILDING_LIBRARY
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll probably need to add availability markups for Apple platforms.

Copy link
Member Author

@vogelsgesang vogelsgesang Nov 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in this particular case we don't need availability markup.

Afaict, availability markup is needed for newly introduced symbols.
However, I am not introducing a new symbol. I am turning an existing symbol into a no-longer used symbol.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're introducing __increment_refcount and __decrement_refcount, so we need to provide some other implementation if they're not available. Using the old implementation seems like a rather obvious solution to me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦 of course...

exception_ptr(const exception_ptr&) _NOEXCEPT;
exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
~exception_ptr() _NOEXCEPT;
# else // _LIBCPP_BUILDING_LIBRARY
_LIBCPP_HIDE_FROM_ABI exception_ptr(const exception_ptr& __other) _NOEXCEPT : __ptr_(__other.__ptr_) {
if (__ptr_)
__increment_refcount(__ptr_);
}
_LIBCPP_HIDE_FROM_ABI exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT {
if (__ptr_ == __other.__ptr_)
return *this;
if (__other.__ptr_)
__increment_refcount(__other.__ptr_);
if (__ptr_)
__decrement_refcount(__ptr_);
__ptr_ = __other.__ptr_;
return *this;
}
_LIBCPP_HIDE_FROM_ABI ~exception_ptr() _NOEXCEPT {
if (__ptr_)
__decrement_refcount(__ptr_);
}
# endif // _LIBCPP_BUILDING_LIBRARY

_LIBCPP_HIDE_FROM_ABI exception_ptr(exception_ptr&& __other) _NOEXCEPT : __ptr_(__other.__ptr_) {
__other.__ptr_ = nullptr;
}
exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI exception_ptr& operator=(exception_ptr&& __other) _NOEXCEPT {
exception_ptr __tmp(std::move(__other));
std::swap(__tmp, *this);
if (__ptr_)
__decrement_refcount(__ptr_);
__ptr_ = __other.__ptr_;
__other.__ptr_ = nullptr;
Comment on lines +111 to +114
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change required?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point.

We have 3 choices:

  1. implement both swap and the move operator, delegate move to swap (previous solution)
  2. implement both swap and the move operator independently (currently in review)
  3. implement only the move operator, and don't provide a specialization for swap

To me, (3) actually feels most natural. My gut feeling tells me that "move" assignments are more frequently used/specialized than swap, so it feels more natural to implement the more common function (move) and delegate the less frequently used (swap) to the other one

I updated the PR accordingly. Please let me know in case you prefer going into a different direction

return *this;
}
~exception_ptr() _NOEXCEPT;

_LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __ptr_ != nullptr; }

Expand All @@ -104,16 +125,10 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
return !(__x == __y);
}

friend _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _NOEXCEPT;

friend _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT;
friend _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
};

inline _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _NOEXCEPT {
std::swap(__x.__ptr_, __y.__ptr_);
}

# if _LIBCPP_HAS_EXCEPTIONS
# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
template <class _Ep>
Expand Down Expand Up @@ -223,6 +238,4 @@ _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
#endif // _LIBCPP_ABI_MICROSOFT
_LIBCPP_END_UNVERSIONED_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,8 @@
{'is_defined': True, 'name': '__ZNSt13bad_exceptionD0Ev', 'type': 'I'}
{'is_defined': True, 'name': '__ZNSt13bad_exceptionD1Ev', 'type': 'I'}
{'is_defined': True, 'name': '__ZNSt13bad_exceptionD2Ev', 'type': 'I'}
{'is_defined': True, 'name': '__ZNSt13exception_ptr23__decrement_refcountEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt13exception_ptr23__increment_refcountEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt13exception_ptrC1ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt13exception_ptrC2ERKS_', 'type': 'FUNC'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,8 @@
{'is_defined': True, 'name': '_ZNSt13bad_exceptionD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13bad_exceptionD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13bad_exceptionD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr23__decrement_refcountEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr23__increment_refcountEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC1ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC2ERKS_', 'type': 'FUNC'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptr23__decrement_refcountEPv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptr23__increment_refcountEPv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptrC1ERKS_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptrC2ERKS_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD0Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD1Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD2Ev', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptr23__decrement_refcountEPv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptr23__increment_refcountEPv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptrC1ERKS_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptrC2ERKS_', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,8 @@
{'is_defined': True, 'name': '__ZNSt13bad_exceptionD0Ev', 'type': 'I'}
{'is_defined': True, 'name': '__ZNSt13bad_exceptionD1Ev', 'type': 'I'}
{'is_defined': True, 'name': '__ZNSt13bad_exceptionD2Ev', 'type': 'I'}
{'is_defined': True, 'name': '__ZNSt13exception_ptr23__decrement_refcountEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt13exception_ptr23__increment_refcountEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt13exception_ptrC1ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt13exception_ptrC2ERKS_', 'type': 'FUNC'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,8 @@
{'is_defined': True, 'name': '_ZNSt13bad_exceptionD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13bad_exceptionD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13bad_exceptionD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr23__decrement_refcountEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr23__increment_refcountEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC1ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC2ERKS_', 'type': 'FUNC'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,8 @@
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr23__decrement_refcountEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr23__increment_refcountEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC1ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC2ERKS_', 'type': 'FUNC'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,8 @@
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr23__decrement_refcountEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr23__increment_refcountEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC1ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC2ERKS_', 'type': 'FUNC'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,8 @@
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD0Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt12experimental19bad_optional_accessD2Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr23__decrement_refcountEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr23__increment_refcountEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptr31__from_native_exception_pointerEPv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC1ERKS_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt13exception_ptrC2ERKS_', 'type': 'FUNC'}
Expand Down
1 change: 0 additions & 1 deletion libcxx/modules/std/exception.inc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export namespace std {
using std::rethrow_exception;
using std::rethrow_if_nested;
using std::set_terminate;
using std::swap;
using std::terminate;
using std::terminate_handler;
using std::throw_with_nested;
Expand Down
3 changes: 3 additions & 0 deletions libcxx/src/exception.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ using namespace __cxxabiv1;
#elif defined(_LIBCPPABI_VERSION)
# include "support/runtime/exception_libcxxabi.ipp"
# include "support/runtime/exception_pointer_cxxabi.ipp"
# include "support/runtime/exception_pointer_refcounted.ipp"
#elif defined(LIBCXXRT)
# include "support/runtime/exception_libcxxrt.ipp"
# include "support/runtime/exception_pointer_cxxabi.ipp"
# include "support/runtime/exception_pointer_refcounted.ipp"
#elif defined(__GLIBCXX__)
# include "support/runtime/exception_glibcxx.ipp"
# include "support/runtime/exception_pointer_glibcxx.ipp"
# include "support/runtime/exception_pointer_refcounted.ipp"
#else
# include "include/atomic_support.h"
# include "support/runtime/exception_fallback.ipp"
Expand Down
23 changes: 4 additions & 19 deletions libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,12 @@

namespace std {

exception_ptr::~exception_ptr() noexcept { __cxa_decrement_exception_refcount(__ptr_); }

exception_ptr::exception_ptr(const exception_ptr& other) noexcept : __ptr_(other.__ptr_) {
__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;
void exception_ptr::__increment_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) noexcept {
__cxa_increment_exception_refcount(__ptr);
}

exception_ptr exception_ptr::__from_native_exception_pointer(void* __e) noexcept {
exception_ptr ptr;
ptr.__ptr_ = __e;
__cxa_increment_exception_refcount(ptr.__ptr_);

return ptr;
void exception_ptr::__decrement_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) noexcept {
__cxa_decrement_exception_refcount(__ptr);
}

nested_exception::nested_exception() noexcept : __ptr_(current_exception()) {}
Expand Down
33 changes: 9 additions & 24 deletions libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@
// 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.
// _M_addref and _M_release and its rethrow_exception function. Fortunately,
// glibcxx's exception_ptr has the same layout as our exception_ptr and we can
// reinterpret_cast between the two.

namespace std {

Expand All @@ -23,34 +22,20 @@ namespace __exception_ptr {
struct exception_ptr {
void* __ptr_;

explicit exception_ptr(void*) noexcept;
exception_ptr(const exception_ptr&) noexcept;
exception_ptr& operator=(const exception_ptr&) noexcept;
~exception_ptr() noexcept;
void _M_addref() noexcept;
void _M_release() noexcept;
};

} // namespace __exception_ptr

[[noreturn]] void rethrow_exception(__exception_ptr::exception_ptr);

exception_ptr::~exception_ptr() noexcept { reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr(); }

exception_ptr::exception_ptr(const exception_ptr& other) noexcept : __ptr_(other.__ptr_) {
new (reinterpret_cast<void*>(this))
__exception_ptr::exception_ptr(reinterpret_cast<const __exception_ptr::exception_ptr&>(other));
}

exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept {
*reinterpret_cast<__exception_ptr::exception_ptr*>(this) =
reinterpret_cast<const __exception_ptr::exception_ptr&>(other);
return *this;
void exception_ptr::__increment_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) noexcept {
reinterpret_cast<__exception_ptr::exception_ptr*>(this)->_M_addref();
}

exception_ptr exception_ptr::__from_native_exception_pointer(void* __e) noexcept {
exception_ptr ptr{};
new (reinterpret_cast<void*>(&ptr)) __exception_ptr::exception_ptr(__e);

return ptr;
void exception_ptr::__decrement_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) noexcept {
reinterpret_cast<__exception_ptr::exception_ptr*>(this)->_M_release();
}

nested_exception::nested_exception() noexcept : __ptr_(current_exception()) {}
Expand Down
37 changes: 37 additions & 0 deletions libcxx/src/support/runtime/exception_pointer_refcounted.ipp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// Provides the common functionality shared between cxxabi and glibcxx.

namespace std {

exception_ptr exception_ptr::__from_native_exception_pointer(void* __e) noexcept {
exception_ptr ptr;
ptr.__ptr_ = __e;
__increment_refcount(ptr.__ptr_);

return ptr;
}

exception_ptr::~exception_ptr() noexcept { __decrement_refcount(__ptr_); }

exception_ptr::exception_ptr(const exception_ptr& other) noexcept : __ptr_(other.__ptr_) {
__increment_refcount(__ptr_);
}

exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept {
if (__ptr_ != other.__ptr_) {
__increment_refcount(other.__ptr_);
__decrement_refcount(__ptr_);
__ptr_ = other.__ptr_;
}
return *this;
}

} // namespace std
17 changes: 2 additions & 15 deletions libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,13 @@

namespace std {

exception_ptr::~exception_ptr() noexcept {
#warning exception_ptr not yet implemented
__libcpp_verbose_abort("exception_ptr not yet implemented\n");
}

exception_ptr::exception_ptr(const exception_ptr& other) noexcept : __ptr_(other.__ptr_) {
#warning exception_ptr not yet implemented
void exception_ptr::__increment_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) noexcept {
__libcpp_verbose_abort("exception_ptr not yet implemented\n");
}

exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept {
#warning exception_ptr not yet implemented
__libcpp_verbose_abort("exception_ptr not yet implemented\n");
}

exception_ptr exception_ptr::__from_native_exception_pointer(void *__e) noexcept {
#warning exception_ptr not yet implemented
void exception_ptr::__decrement_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) noexcept {
__libcpp_verbose_abort("exception_ptr not yet implemented\n");
}

Expand All @@ -40,7 +30,6 @@ nested_exception::~nested_exception() noexcept {}
#endif

[[noreturn]] void nested_exception::rethrow_nested() const {
#warning exception_ptr not yet implemented
__libcpp_verbose_abort("exception_ptr not yet implemented\n");
#if 0
if (__ptr_ == nullptr)
Expand All @@ -50,12 +39,10 @@ nested_exception::~nested_exception() noexcept {}
}

exception_ptr current_exception() noexcept {
#warning exception_ptr not yet implemented
__libcpp_verbose_abort("exception_ptr not yet implemented\n");
}

[[noreturn]] void rethrow_exception(exception_ptr p) {
#warning exception_ptr not yet implemented
__libcpp_verbose_abort("exception_ptr not yet implemented\n");
}

Expand Down
Loading