[libcxx-commits] [libcxx] [libc++] Inline fast path for`exception_ptr` copy constructor & destructor (PR #165909)
Adrian Vogelsgesang via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Nov 10 08:20:51 PST 2025
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/165909
>From b97ad48bac69f975dafcc2adaa75909ae70371f9 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Fri, 31 Oct 2025 16:06:22 +0000
Subject: [PATCH 01/13] [libc++] Inline copy constructor & destructor for
`std::exception_ptr`
---
libcxx/include/__exception/exception_ptr.h | 65 +++++++++++++++++--
libcxx/src/exception.cpp | 1 +
.../runtime/exception_pointer_cxxabi.ipp | 15 ++---
.../runtime/exception_pointer_glibcxx.ipp | 27 +++-----
.../exception_pointer_unimplemented.ipp | 9 +--
5 files changed, 77 insertions(+), 40 deletions(-)
diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h
index aef036a2c9586..44817d7701bb8 100644
--- a/libcxx/include/__exception/exception_ptr.h
+++ b/libcxx/include/__exception/exception_ptr.h
@@ -31,6 +31,28 @@ _LIBCPP_PUSH_MACROS
#ifndef _LIBCPP_ABI_MICROSOFT
+// Previously, parts of exception_ptr were defined out-of-line, which prevented
+// useful compiler optimizations. Changing the out-of-line definitions to inline
+// definitions is an ABI break, however. To prevent this, we have to make sure
+// the symbols remain available in the libc++ library, in addition to being
+// defined inline here in this header.
+// To this end, we use _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE macro:
+// The macro is defined as empty for src/exception.cpp, forcing the definitions of
+// the functions to be emitted and included in the library. When users of libc++
+// compile their code, the __gnu_inline__ attribute will suppress generation of
+// these functions while making their definitions available for inlining.
+# ifdef _LIBCPP_EMIT_CODE_FOR_EXCEPTION_PTR
+# define _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE _LIBCPP_EXPORTED_FROM_ABI
+# else
+# if !__has_cpp_attribute(__gnu__::__gnu_inline__)
+# error "GNU inline attribute is not supported"
+# endif
+# define _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE [[__gnu__::__gnu_inline__]] inline
+# endif
+
+_LIBCPP_DIAGNOSTIC_PUSH
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wgnu-inline-cpp-without-extern")
+
# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
namespace __cxxabiv1 {
@@ -68,6 +90,17 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _
class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
void* __ptr_;
+ static void __do_increment_refcount(void* __ptr) _NOEXCEPT;
+ static void __do_decrement_refcount(void* __ptr) _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI static void __increment_refcount(void* __ptr) _NOEXCEPT {
+ if (__ptr)
+ __do_increment_refcount(__ptr);
+ }
+ _LIBCPP_HIDE_FROM_ABI static void __decrement_refcount(void* __ptr) _NOEXCEPT {
+ if (__ptr)
+ __do_decrement_refcount(__ptr);
+ }
+
static exception_ptr __from_native_exception_pointer(void*) _NOEXCEPT;
template <class _Ep>
@@ -82,17 +115,18 @@ 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_() {}
- exception_ptr(const exception_ptr&) _NOEXCEPT;
+ _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr(const exception_ptr&) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI exception_ptr(exception_ptr&& __other) _NOEXCEPT : __ptr_(__other.__ptr_) {
__other.__ptr_ = nullptr;
}
- exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
+ _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE 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);
+ __decrement_refcount(__ptr_);
+ __ptr_ = __other.__ptr_;
+ __other.__ptr_ = nullptr;
return *this;
}
- ~exception_ptr() _NOEXCEPT;
+ _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE ~exception_ptr() _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __ptr_ != nullptr; }
@@ -110,6 +144,25 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
friend _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
};
+// Must be defined outside the class definition due to _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE
+_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr::exception_ptr(const exception_ptr& __other) _NOEXCEPT
+ : __ptr_(__other.__ptr_) {
+ __increment_refcount(__ptr_);
+}
+
+// Must be defined outside the class definition due to _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE
+_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE 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;
+}
+
+// Must be defined outside the class definition due to _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE
+_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr::~exception_ptr() _NOEXCEPT { __decrement_refcount(__ptr_); }
+
inline _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _NOEXCEPT {
std::swap(__x.__ptr_, __y.__ptr_);
}
@@ -223,6 +276,8 @@ _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
#endif // _LIBCPP_ABI_MICROSOFT
_LIBCPP_END_UNVERSIONED_NAMESPACE_STD
+_LIBCPP_DIAGNOSTIC_POP
+
_LIBCPP_POP_MACROS
#endif // _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
diff --git a/libcxx/src/exception.cpp b/libcxx/src/exception.cpp
index ac6324cd9fe35..9dd9b0c9938fd 100644
--- a/libcxx/src/exception.cpp
+++ b/libcxx/src/exception.cpp
@@ -8,6 +8,7 @@
#define _LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION
#define _LIBCPP_DISABLE_DEPRECATION_WARNINGS
+#define _LIBCPP_EMIT_CODE_FOR_EXCEPTION_PTR
#include <exception>
#include <new>
diff --git a/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp b/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
index 8f5c2060bb06c..e09bf8981263f 100644
--- a/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
+++ b/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
@@ -13,19 +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_);
+void exception_ptr::__do_increment_refcount(void* __ptr) 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;
+void exception_ptr::__do_decrement_refcount(void* __ptr) noexcept {
+ __cxa_decrement_exception_refcount(__ptr);
}
exception_ptr exception_ptr::__from_native_exception_pointer(void* __e) noexcept {
diff --git a/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp b/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
index 174b44ce0e6f7..c7b2e343b5f09 100644
--- a/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
+++ b/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
@@ -7,14 +7,14 @@
//
//===----------------------------------------------------------------------===//
+
// 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.
+// _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 {
@@ -23,27 +23,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));
+void exception_ptr::__do_increment_refcount(void* __ptr) noexcept {
+ reinterpret_cast<__exception_ptr::exception_ptr*>(this)->_M_addref();
}
-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::__do_decrement_refcount(void* __ptr) noexcept {
+ reinterpret_cast<__exception_ptr::exception_ptr*>(this)->_M_release();
}
exception_ptr exception_ptr::__from_native_exception_pointer(void* __e) noexcept {
diff --git a/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp b/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
index 05a71ce34e5ac..78be16bf95188 100644
--- a/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
+++ b/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
@@ -11,17 +11,12 @@
namespace std {
-exception_ptr::~exception_ptr() noexcept {
+void exception_ptr::__do_increment_refcount(void* __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
- __libcpp_verbose_abort("exception_ptr not yet implemented\n");
-}
-
-exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept {
+void exception_ptr::__do_decrement_refcount(void* __ptr) noexcept {
#warning exception_ptr not yet implemented
__libcpp_verbose_abort("exception_ptr not yet implemented\n");
}
>From 419f64d9fe4964f4a3fe26565975a2378b579be6 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Tue, 4 Nov 2025 11:02:44 +0000
Subject: [PATCH 02/13] Add release note
---
libcxx/docs/ReleaseNotes/22.rst | 3 +++
1 file changed, 3 insertions(+)
diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst
index a6a0ac8670fb5..5734f33e13498 100644
--- a/libcxx/docs/ReleaseNotes/22.rst
+++ b/libcxx/docs/ReleaseNotes/22.rst
@@ -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
-------------------------
>From b32d1be2a61ad8904bf9835260ab34884535c7e7 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Tue, 4 Nov 2025 11:04:24 +0000
Subject: [PATCH 03/13] Support new visibility attribute in clang-tidy check
---
libcxx/test/tools/clang_tidy_checks/hide_from_abi.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libcxx/test/tools/clang_tidy_checks/hide_from_abi.cpp b/libcxx/test/tools/clang_tidy_checks/hide_from_abi.cpp
index 38bf62019599e..3740ffb7f7149 100644
--- a/libcxx/test/tools/clang_tidy_checks/hide_from_abi.cpp
+++ b/libcxx/test/tools/clang_tidy_checks/hide_from_abi.cpp
@@ -23,7 +23,8 @@ hide_from_abi::hide_from_abi(llvm::StringRef name, clang::tidy::ClangTidyContext
void hide_from_abi::registerMatchers(clang::ast_matchers::MatchFinder* finder) {
using namespace clang::ast_matchers;
- auto has_hide_from_abi_attr = anyOf(hasAttr(clang::attr::Visibility), hasAttr(clang::attr::AbiTag));
+ auto has_hide_from_abi_attr =
+ anyOf(hasAttr(clang::attr::Visibility), hasAttr(clang::attr::AbiTag), hasAttr(clang::attr::GNUInline));
finder->addMatcher(
functionDecl(
>From ddaf78e5ea8bd9b0356bbe3ef59c2b3a23e32145 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Tue, 4 Nov 2025 11:36:55 +0000
Subject: [PATCH 04/13] Update ABI list
---
...64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist | 2 ++
...linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist | 2 ++
...powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist | 2 ++
...werpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist | 2 ++
...64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist | 2 ++
...linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist | 2 ++
...unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist | 2 ++
...known-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist | 2 ++
...own-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist | 2 ++
9 files changed, 18 insertions(+)
diff --git a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index 3a1d8950c2db0..848d32be3c2e0 100644
--- a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -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__do_decrement_refcountEPv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt13exception_ptr23__do_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'}
diff --git a/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
index 313de84df20e8..41749d900c16c 100644
--- a/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -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__do_decrement_refcountEPv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt13exception_ptr23__do_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'}
diff --git a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 99cde72885cf2..5095d43beb57e 100644
--- a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -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__do_decrement_refcountEPv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptr23__do_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'}
diff --git a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 577d6cf759a77..41a56e2fec337 100644
--- a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -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__do_decrement_refcountEPv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
+{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptr23__do_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'}
diff --git a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index 5173a1a76b81a..8290adf000088 100644
--- a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -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__do_decrement_refcountEPv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt13exception_ptr23__do_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'}
diff --git a/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
index 1be7d8a2ac20b..b084398e16caa 100644
--- a/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -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__do_decrement_refcountEPv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt13exception_ptr23__do_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'}
diff --git a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
index 40ae625d3bd69..e5e255ce4548d 100644
--- a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -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__do_decrement_refcountEPv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt13exception_ptr23__do_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'}
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
index 90166073b135f..6ef9f85d960da 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -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__do_decrement_refcountEPv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt13exception_ptr23__do_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'}
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
index 5855c17cf11ed..7c085135837ff 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
@@ -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__do_decrement_refcountEPv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt13exception_ptr23__do_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'}
>From a02680164c7a4c77ae80060855450353282a9648 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Tue, 4 Nov 2025 13:11:57 +0000
Subject: [PATCH 05/13] Fix Windows build by positioning
`_LIBCPP_DIAGNOSTIC_POP` correctly
---
libcxx/include/__exception/exception_ptr.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h
index 44817d7701bb8..c6e0b88b006fe 100644
--- a/libcxx/include/__exception/exception_ptr.h
+++ b/libcxx/include/__exception/exception_ptr.h
@@ -232,6 +232,8 @@ _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep) _NOEXCEPT {
}
# endif // _LIBCPP_HAS_EXCEPTIONS
+_LIBCPP_DIAGNOSTIC_POP
+
#else // _LIBCPP_ABI_MICROSOFT
class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
@@ -276,8 +278,6 @@ _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
#endif // _LIBCPP_ABI_MICROSOFT
_LIBCPP_END_UNVERSIONED_NAMESPACE_STD
-_LIBCPP_DIAGNOSTIC_POP
-
_LIBCPP_POP_MACROS
#endif // _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
>From f787db6411f12b26641ea167f833cfe61163bc0a Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Thu, 6 Nov 2025 06:55:17 +0000
Subject: [PATCH 06/13] Address review comments
---
libcxx/include/__exception/exception_ptr.h | 48 ++++++++-----------
...bcxxabi.v1.stable.exceptions.nonew.abilist | 4 +-
...bcxxabi.v1.stable.exceptions.nonew.abilist | 4 +-
...bcxxabi.v1.stable.exceptions.nonew.abilist | 4 +-
...bcxxabi.v1.stable.exceptions.nonew.abilist | 4 +-
...bcxxabi.v1.stable.exceptions.nonew.abilist | 4 +-
...bcxxabi.v1.stable.exceptions.nonew.abilist | 4 +-
...bcxxabi.v1.stable.exceptions.nonew.abilist | 4 +-
...bcxxabi.v1.stable.exceptions.nonew.abilist | 4 +-
...xxabi.v1.stable.noexceptions.nonew.abilist | 4 +-
.../runtime/exception_pointer_cxxabi.ipp | 19 +++++++-
.../runtime/exception_pointer_glibcxx.ipp | 19 +++++++-
.../exception_pointer_unimplemented.ipp | 21 ++++++--
13 files changed, 90 insertions(+), 53 deletions(-)
diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h
index c6e0b88b006fe..27727158b62fe 100644
--- a/libcxx/include/__exception/exception_ptr.h
+++ b/libcxx/include/__exception/exception_ptr.h
@@ -36,18 +36,10 @@ _LIBCPP_PUSH_MACROS
// definitions is an ABI break, however. To prevent this, we have to make sure
// the symbols remain available in the libc++ library, in addition to being
// defined inline here in this header.
-// To this end, we use _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE macro:
-// The macro is defined as empty for src/exception.cpp, forcing the definitions of
-// the functions to be emitted and included in the library. When users of libc++
-// compile their code, the __gnu_inline__ attribute will suppress generation of
-// these functions while making their definitions available for inlining.
-# ifdef _LIBCPP_EMIT_CODE_FOR_EXCEPTION_PTR
+# ifdef _LIBCPP_BUILDING_LIBRARY
# define _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE _LIBCPP_EXPORTED_FROM_ABI
# else
-# if !__has_cpp_attribute(__gnu__::__gnu_inline__)
-# error "GNU inline attribute is not supported"
-# endif
-# define _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE [[__gnu__::__gnu_inline__]] inline
+# define _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE _LIBCPP_HIDE_FROM_ABI
# endif
_LIBCPP_DIAGNOSTIC_PUSH
@@ -90,16 +82,8 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _
class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
void* __ptr_;
- static void __do_increment_refcount(void* __ptr) _NOEXCEPT;
- static void __do_decrement_refcount(void* __ptr) _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI static void __increment_refcount(void* __ptr) _NOEXCEPT {
- if (__ptr)
- __do_increment_refcount(__ptr);
- }
- _LIBCPP_HIDE_FROM_ABI static void __decrement_refcount(void* __ptr) _NOEXCEPT {
- if (__ptr)
- __do_decrement_refcount(__ptr);
- }
+ static void __increment_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) _NOEXCEPT;
+ static void __decrement_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) _NOEXCEPT;
static exception_ptr __from_native_exception_pointer(void*) _NOEXCEPT;
@@ -121,7 +105,8 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
}
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI exception_ptr& operator=(exception_ptr&& __other) _NOEXCEPT {
- __decrement_refcount(__ptr_);
+ if (__ptr_)
+ __decrement_refcount(__ptr_);
__ptr_ = __other.__ptr_;
__other.__ptr_ = nullptr;
return *this;
@@ -144,24 +129,31 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
friend _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
};
-// Must be defined outside the class definition due to _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE
+#ifndef _LIBCPP_BUILDING_LIBRARY
+
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr::exception_ptr(const exception_ptr& __other) _NOEXCEPT
: __ptr_(__other.__ptr_) {
- __increment_refcount(__ptr_);
+ if (__ptr_)
+ __increment_refcount(__ptr_);
}
-// Must be defined outside the class definition due to _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr& exception_ptr::operator=(const exception_ptr& __other) _NOEXCEPT {
if (__ptr_ != __other.__ptr_) {
- __increment_refcount(__other.__ptr_);
- __decrement_refcount(__ptr_);
+ if (__other.__ptr_)
+ __increment_refcount(__other.__ptr_);
+ if (__ptr_)
+ __decrement_refcount(__ptr_);
__ptr_ = __other.__ptr_;
}
return *this;
}
-// Must be defined outside the class definition due to _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE
-_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr::~exception_ptr() _NOEXCEPT { __decrement_refcount(__ptr_); }
+_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr::~exception_ptr() _NOEXCEPT {
+ if (__ptr_)
+ __decrement_refcount(__ptr_);
+}
+
+#endif // _LIBCPP_BUILDING_LIBRARY
inline _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _NOEXCEPT {
std::swap(__x.__ptr_, __y.__ptr_);
diff --git a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index 848d32be3c2e0..c8a87ff1e5b65 100644
--- a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -858,8 +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__do_decrement_refcountEPv', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt13exception_ptr23__do_increment_refcountEPv', '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'}
diff --git a/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
index 41749d900c16c..5aba2844dcaee 100644
--- a/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -494,8 +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__do_decrement_refcountEPv', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt13exception_ptr23__do_increment_refcountEPv', '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'}
diff --git a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 5095d43beb57e..a46e8532599e2 100644
--- a/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -250,8 +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__do_decrement_refcountEPv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptr23__do_increment_refcountEPv', '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'}
diff --git a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
index 41a56e2fec337..8eeb101737762 100644
--- a/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/powerpc64-ibm-aix.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -250,8 +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__do_decrement_refcountEPv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
-{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt13exception_ptr23__do_increment_refcountEPv', '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'}
diff --git a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index 8290adf000088..520a26bfdd389 100644
--- a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -857,8 +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__do_decrement_refcountEPv', 'type': 'FUNC'}
-{'is_defined': True, 'name': '__ZNSt13exception_ptr23__do_increment_refcountEPv', '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'}
diff --git a/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
index b084398e16caa..7076e2993be47 100644
--- a/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -494,8 +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__do_decrement_refcountEPv', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt13exception_ptr23__do_increment_refcountEPv', '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'}
diff --git a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
index e5e255ce4548d..5c3bd954097fd 100644
--- a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -525,8 +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__do_decrement_refcountEPv', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt13exception_ptr23__do_increment_refcountEPv', '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'}
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
index 6ef9f85d960da..fd8b7ecfb3e64 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -523,8 +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__do_decrement_refcountEPv', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt13exception_ptr23__do_increment_refcountEPv', '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'}
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
index 7c085135837ff..ec4548b3e34f0 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.noexceptions.nonew.abilist
@@ -494,8 +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__do_decrement_refcountEPv', 'type': 'FUNC'}
-{'is_defined': True, 'name': '_ZNSt13exception_ptr23__do_increment_refcountEPv', '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'}
diff --git a/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp b/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
index e09bf8981263f..30d185c9d674b 100644
--- a/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
+++ b/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
@@ -13,11 +13,11 @@
namespace std {
-void exception_ptr::__do_increment_refcount(void* __ptr) noexcept {
+void exception_ptr::__increment_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) noexcept {
__cxa_increment_exception_refcount(__ptr);
}
-void exception_ptr::__do_decrement_refcount(void* __ptr) noexcept {
+void exception_ptr::__decrement_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) noexcept {
__cxa_decrement_exception_refcount(__ptr);
}
@@ -29,6 +29,21 @@ exception_ptr exception_ptr::__from_native_exception_pointer(void* __e) noexcept
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;
+}
+
nested_exception::nested_exception() noexcept : __ptr_(current_exception()) {}
nested_exception::~nested_exception() noexcept {}
diff --git a/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp b/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
index c7b2e343b5f09..d9da4e2f19fd9 100644
--- a/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
+++ b/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
@@ -31,11 +31,11 @@ struct exception_ptr {
[[noreturn]] void rethrow_exception(__exception_ptr::exception_ptr);
-void exception_ptr::__do_increment_refcount(void* __ptr) noexcept {
+void exception_ptr::__increment_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) noexcept {
reinterpret_cast<__exception_ptr::exception_ptr*>(this)->_M_addref();
}
-void exception_ptr::__do_decrement_refcount(void* __ptr) noexcept {
+void exception_ptr::__decrement_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) noexcept {
reinterpret_cast<__exception_ptr::exception_ptr*>(this)->_M_release();
}
@@ -46,6 +46,21 @@ exception_ptr exception_ptr::__from_native_exception_pointer(void* __e) noexcept
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;
+}
+
nested_exception::nested_exception() noexcept : __ptr_(current_exception()) {}
[[noreturn]] void nested_exception::rethrow_nested() const {
diff --git a/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp b/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
index 78be16bf95188..37809aa05fa91 100644
--- a/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
+++ b/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
@@ -11,12 +11,12 @@
namespace std {
-void exception_ptr::__do_increment_refcount(void* __ptr) noexcept {
-#warning exception_ptr not yet implemented
+void exception_ptr::__increment_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) noexcept {
+ #warning exception_ptr not yet implemented
__libcpp_verbose_abort("exception_ptr not yet implemented\n");
}
-void exception_ptr::__do_decrement_refcount(void* __ptr) noexcept {
+void exception_ptr::__decrement_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) noexcept {
#warning exception_ptr not yet implemented
__libcpp_verbose_abort("exception_ptr not yet implemented\n");
}
@@ -26,6 +26,21 @@ exception_ptr exception_ptr::__from_native_exception_pointer(void *__e) noexcept
__libcpp_verbose_abort("exception_ptr not yet implemented\n");
}
+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
+ __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");
+}
+
nested_exception::nested_exception() noexcept : __ptr_(current_exception()) {}
#if !defined(__GLIBCXX__)
>From d731778dda453a49237a6efbb4d958e637f9e4df Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Thu, 6 Nov 2025 07:02:09 +0000
Subject: [PATCH 07/13] Remove unnecessary changes
---
libcxx/include/__exception/exception_ptr.h | 5 -----
libcxx/src/exception.cpp | 1 -
libcxx/src/support/runtime/exception_pointer_glibcxx.ipp | 1 -
libcxx/test/tools/clang_tidy_checks/hide_from_abi.cpp | 3 +--
4 files changed, 1 insertion(+), 9 deletions(-)
diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h
index 27727158b62fe..ff4dd98f88f66 100644
--- a/libcxx/include/__exception/exception_ptr.h
+++ b/libcxx/include/__exception/exception_ptr.h
@@ -42,9 +42,6 @@ _LIBCPP_PUSH_MACROS
# define _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE _LIBCPP_HIDE_FROM_ABI
# endif
-_LIBCPP_DIAGNOSTIC_PUSH
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wgnu-inline-cpp-without-extern")
-
# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
namespace __cxxabiv1 {
@@ -224,8 +221,6 @@ _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep) _NOEXCEPT {
}
# endif // _LIBCPP_HAS_EXCEPTIONS
-_LIBCPP_DIAGNOSTIC_POP
-
#else // _LIBCPP_ABI_MICROSOFT
class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
diff --git a/libcxx/src/exception.cpp b/libcxx/src/exception.cpp
index 9dd9b0c9938fd..ac6324cd9fe35 100644
--- a/libcxx/src/exception.cpp
+++ b/libcxx/src/exception.cpp
@@ -8,7 +8,6 @@
#define _LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION
#define _LIBCPP_DISABLE_DEPRECATION_WARNINGS
-#define _LIBCPP_EMIT_CODE_FOR_EXCEPTION_PTR
#include <exception>
#include <new>
diff --git a/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp b/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
index d9da4e2f19fd9..40a5f116d7ebf 100644
--- a/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
+++ b/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
// 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
diff --git a/libcxx/test/tools/clang_tidy_checks/hide_from_abi.cpp b/libcxx/test/tools/clang_tidy_checks/hide_from_abi.cpp
index 3740ffb7f7149..38bf62019599e 100644
--- a/libcxx/test/tools/clang_tidy_checks/hide_from_abi.cpp
+++ b/libcxx/test/tools/clang_tidy_checks/hide_from_abi.cpp
@@ -23,8 +23,7 @@ hide_from_abi::hide_from_abi(llvm::StringRef name, clang::tidy::ClangTidyContext
void hide_from_abi::registerMatchers(clang::ast_matchers::MatchFinder* finder) {
using namespace clang::ast_matchers;
- auto has_hide_from_abi_attr =
- anyOf(hasAttr(clang::attr::Visibility), hasAttr(clang::attr::AbiTag), hasAttr(clang::attr::GNUInline));
+ auto has_hide_from_abi_attr = anyOf(hasAttr(clang::attr::Visibility), hasAttr(clang::attr::AbiTag));
finder->addMatcher(
functionDecl(
>From a7316f9a46ed62f3b987665da525ceb63b3fce84 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Thu, 6 Nov 2025 07:20:13 +0000
Subject: [PATCH 08/13] CI fixes
---
libcxx/include/__exception/exception_ptr.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h
index ff4dd98f88f66..6db24880c856c 100644
--- a/libcxx/include/__exception/exception_ptr.h
+++ b/libcxx/include/__exception/exception_ptr.h
@@ -37,7 +37,7 @@ _LIBCPP_PUSH_MACROS
// the symbols remain available in the libc++ library, in addition to being
// defined inline here in this header.
# ifdef _LIBCPP_BUILDING_LIBRARY
-# define _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE _LIBCPP_EXPORTED_FROM_ABI
+# define _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE
# else
# define _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE _LIBCPP_HIDE_FROM_ABI
# endif
@@ -126,7 +126,7 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
friend _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
};
-#ifndef _LIBCPP_BUILDING_LIBRARY
+# ifndef _LIBCPP_BUILDING_LIBRARY
_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr::exception_ptr(const exception_ptr& __other) _NOEXCEPT
: __ptr_(__other.__ptr_) {
@@ -150,7 +150,7 @@ _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr::~exception_ptr() _NOEXCEPT {
__decrement_refcount(__ptr_);
}
-#endif // _LIBCPP_BUILDING_LIBRARY
+# endif // _LIBCPP_BUILDING_LIBRARY
inline _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _NOEXCEPT {
std::swap(__x.__ptr_, __y.__ptr_);
>From 2ef680d622cd1113b75e8bb5e8a56588d632430f Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Thu, 6 Nov 2025 07:39:23 +0000
Subject: [PATCH 09/13] More CI fixes
---
libcxx/include/__exception/exception_ptr.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h
index 6db24880c856c..726b409754a15 100644
--- a/libcxx/include/__exception/exception_ptr.h
+++ b/libcxx/include/__exception/exception_ptr.h
@@ -128,13 +128,13 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
# ifndef _LIBCPP_BUILDING_LIBRARY
-_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr::exception_ptr(const exception_ptr& __other) _NOEXCEPT
+_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE inline exception_ptr::exception_ptr(const exception_ptr& __other) _NOEXCEPT
: __ptr_(__other.__ptr_) {
if (__ptr_)
__increment_refcount(__ptr_);
}
-_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr& exception_ptr::operator=(const exception_ptr& __other) _NOEXCEPT {
+_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE inline exception_ptr& exception_ptr::operator=(const exception_ptr& __other) _NOEXCEPT {
if (__ptr_ != __other.__ptr_) {
if (__other.__ptr_)
__increment_refcount(__other.__ptr_);
@@ -145,7 +145,7 @@ _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr& exception_ptr::operator=(con
return *this;
}
-_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr::~exception_ptr() _NOEXCEPT {
+_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE inline exception_ptr::~exception_ptr() _NOEXCEPT {
if (__ptr_)
__decrement_refcount(__ptr_);
}
>From 455a2a6d4fdf1cb44c4cca46532ced6b35e3237f Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Mon, 10 Nov 2025 12:27:19 +0000
Subject: [PATCH 10/13] Simplify `#ifdef` in header
---
libcxx/include/__exception/exception_ptr.h | 70 +++++++++-------------
1 file changed, 28 insertions(+), 42 deletions(-)
diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h
index 726b409754a15..f59d0f4cdfb94 100644
--- a/libcxx/include/__exception/exception_ptr.h
+++ b/libcxx/include/__exception/exception_ptr.h
@@ -31,17 +31,6 @@ _LIBCPP_PUSH_MACROS
#ifndef _LIBCPP_ABI_MICROSOFT
-// Previously, parts of exception_ptr were defined out-of-line, which prevented
-// useful compiler optimizations. Changing the out-of-line definitions to inline
-// definitions is an ABI break, however. To prevent this, we have to make sure
-// the symbols remain available in the libc++ library, in addition to being
-// defined inline here in this header.
-# ifdef _LIBCPP_BUILDING_LIBRARY
-# define _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE
-# else
-# define _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE _LIBCPP_HIDE_FROM_ABI
-# endif
-
# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
namespace __cxxabiv1 {
@@ -79,8 +68,8 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _
class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
void* __ptr_;
- static void __increment_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) _NOEXCEPT;
- static void __decrement_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) _NOEXCEPT;
+ 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;
@@ -96,11 +85,35 @@ 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_() {}
- _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr(const exception_ptr&) _NOEXCEPT;
+// These symbols are still exported from the library to prevent ABI breakage.
+# ifdef _LIBCPP_BUILDING_LIBRARY
+ 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&) _NOEXCEPT : __ptr_(__other.__ptr_) {
+ if (__ptr_)
+ __increment_refcount(__ptr_);
+ }
+ _LIBCPP_HIDE_FROM_ABI exception_ptr& operator=(const exception_ptr&) _NOEXCEPT {
+ if (__ptr_ != __other.__ptr_) {
+ 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;
}
- _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI exception_ptr& operator=(exception_ptr&& __other) _NOEXCEPT {
if (__ptr_)
__decrement_refcount(__ptr_);
@@ -108,7 +121,6 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
__other.__ptr_ = nullptr;
return *this;
}
- _LIBCPP_EXPORTED_FROM_LIB_INLINEABLE ~exception_ptr() _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __ptr_ != nullptr; }
@@ -126,32 +138,6 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
friend _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr);
};
-# ifndef _LIBCPP_BUILDING_LIBRARY
-
-_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE inline exception_ptr::exception_ptr(const exception_ptr& __other) _NOEXCEPT
- : __ptr_(__other.__ptr_) {
- if (__ptr_)
- __increment_refcount(__ptr_);
-}
-
-_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE inline exception_ptr& exception_ptr::operator=(const exception_ptr& __other) _NOEXCEPT {
- if (__ptr_ != __other.__ptr_) {
- if (__other.__ptr_)
- __increment_refcount(__other.__ptr_);
- if (__ptr_)
- __decrement_refcount(__ptr_);
- __ptr_ = __other.__ptr_;
- }
- return *this;
-}
-
-_LIBCPP_EXPORTED_FROM_LIB_INLINEABLE inline exception_ptr::~exception_ptr() _NOEXCEPT {
- if (__ptr_)
- __decrement_refcount(__ptr_);
-}
-
-# endif // _LIBCPP_BUILDING_LIBRARY
-
inline _LIBCPP_HIDE_FROM_ABI void swap(exception_ptr& __x, exception_ptr& __y) _NOEXCEPT {
std::swap(__x.__ptr_, __y.__ptr_);
}
>From 68f72ea30eb60c97063c284689a67f59f9f595f4 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Mon, 10 Nov 2025 12:29:15 +0000
Subject: [PATCH 11/13] Simlify `#warning` in exception_unimplemented
---
.../runtime/exception_pointer_unimplemented.ipp | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp b/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
index 37809aa05fa91..ac8176826bea9 100644
--- a/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
+++ b/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
@@ -11,33 +11,29 @@
namespace std {
+#warning exception_ptr not yet implemented
+
void exception_ptr::__increment_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) noexcept {
- #warning exception_ptr not yet implemented
__libcpp_verbose_abort("exception_ptr not yet implemented\n");
}
void exception_ptr::__decrement_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCAPE void* __ptr) 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
__libcpp_verbose_abort("exception_ptr not yet implemented\n");
}
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
__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");
}
@@ -50,7 +46,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)
@@ -60,12 +55,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");
}
>From 12373fa5436d2cd62ed3f32d8f37076a623103de Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Mon, 10 Nov 2025 15:54:02 +0000
Subject: [PATCH 12/13] Deduplicate ref-counted implementations
---
libcxx/src/exception.cpp | 3 ++
.../runtime/exception_pointer_cxxabi.ipp | 23 ------------
.../runtime/exception_pointer_glibcxx.ipp | 22 -----------
.../runtime/exception_pointer_refcounted.ipp | 37 +++++++++++++++++++
.../exception_pointer_unimplemented.ipp | 16 --------
5 files changed, 40 insertions(+), 61 deletions(-)
create mode 100644 libcxx/src/support/runtime/exception_pointer_refcounted.ipp
diff --git a/libcxx/src/exception.cpp b/libcxx/src/exception.cpp
index ac6324cd9fe35..50650fe7d6f05 100644
--- a/libcxx/src/exception.cpp
+++ b/libcxx/src/exception.cpp
@@ -24,12 +24,15 @@ using namespace __cxxabiv1;
# include "support/runtime/exception_pointer_msvc.ipp"
#elif defined(_LIBCPPABI_VERSION)
# include "support/runtime/exception_libcxxabi.ipp"
+# include "support/runtime/exception_pointer_refcounted.ipp"
# include "support/runtime/exception_pointer_cxxabi.ipp"
#elif defined(LIBCXXRT)
# include "support/runtime/exception_libcxxrt.ipp"
+# include "support/runtime/exception_pointer_refcounted.ipp"
# include "support/runtime/exception_pointer_cxxabi.ipp"
#elif defined(__GLIBCXX__)
# include "support/runtime/exception_glibcxx.ipp"
+# include "support/runtime/exception_pointer_refcounted.ipp"
# include "support/runtime/exception_pointer_glibcxx.ipp"
#else
# include "include/atomic_support.h"
diff --git a/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp b/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
index 30d185c9d674b..1464082c8a098 100644
--- a/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
+++ b/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
@@ -21,29 +21,6 @@ void exception_ptr::__decrement_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCA
__cxa_decrement_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;
-}
-
-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;
-}
-
nested_exception::nested_exception() noexcept : __ptr_(current_exception()) {}
nested_exception::~nested_exception() noexcept {}
diff --git a/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp b/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
index 40a5f116d7ebf..abf1f66b146ed 100644
--- a/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
+++ b/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp
@@ -38,28 +38,6 @@ void exception_ptr::__decrement_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCA
reinterpret_cast<__exception_ptr::exception_ptr*>(this)->_M_release();
}
-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;
-}
-
-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;
-}
-
nested_exception::nested_exception() noexcept : __ptr_(current_exception()) {}
[[noreturn]] void nested_exception::rethrow_nested() const {
diff --git a/libcxx/src/support/runtime/exception_pointer_refcounted.ipp b/libcxx/src/support/runtime/exception_pointer_refcounted.ipp
new file mode 100644
index 0000000000000..0b71e52cb2423
--- /dev/null
+++ b/libcxx/src/support/runtime/exception_pointer_refcounted.ipp
@@ -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
diff --git a/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp b/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
index ac8176826bea9..56d425e7b7c4d 100644
--- a/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
+++ b/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp
@@ -21,22 +21,6 @@ void exception_ptr::__decrement_refcount([[__gnu__::__nonnull__]] _LIBCPP_NOESCA
__libcpp_verbose_abort("exception_ptr not yet implemented\n");
}
-exception_ptr exception_ptr::__from_native_exception_pointer(void *__e) noexcept {
- __libcpp_verbose_abort("exception_ptr not yet implemented\n");
-}
-
-exception_ptr::~exception_ptr() noexcept {
- __libcpp_verbose_abort("exception_ptr not yet implemented\n");
-}
-
-exception_ptr::exception_ptr(const exception_ptr& other) noexcept : __ptr_(other.__ptr_) {
- __libcpp_verbose_abort("exception_ptr not yet implemented\n");
-}
-
-exception_ptr& exception_ptr::operator=(const exception_ptr& other) noexcept {
- __libcpp_verbose_abort("exception_ptr not yet implemented\n");
-}
-
nested_exception::nested_exception() noexcept : __ptr_(current_exception()) {}
#if !defined(__GLIBCXX__)
>From 4c75c4ee82e42764e431e1db7cde529d898301d9 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Mon, 10 Nov 2025 16:07:32 +0000
Subject: [PATCH 13/13] Formatting
---
libcxx/include/__exception/exception_ptr.h | 2 +-
libcxx/src/exception.cpp | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h
index f59d0f4cdfb94..459a05d50c10f 100644
--- a/libcxx/include/__exception/exception_ptr.h
+++ b/libcxx/include/__exception/exception_ptr.h
@@ -90,7 +90,7 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
exception_ptr(const exception_ptr&) _NOEXCEPT;
exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
~exception_ptr() _NOEXCEPT;
-# else // _LIBCPP_BUILDING_LIBRARY
+# else // _LIBCPP_BUILDING_LIBRARY
_LIBCPP_HIDE_FROM_ABI exception_ptr(const exception_ptr&) _NOEXCEPT : __ptr_(__other.__ptr_) {
if (__ptr_)
__increment_refcount(__ptr_);
diff --git a/libcxx/src/exception.cpp b/libcxx/src/exception.cpp
index 50650fe7d6f05..6f24e7dd467b3 100644
--- a/libcxx/src/exception.cpp
+++ b/libcxx/src/exception.cpp
@@ -24,16 +24,16 @@ using namespace __cxxabiv1;
# include "support/runtime/exception_pointer_msvc.ipp"
#elif defined(_LIBCPPABI_VERSION)
# include "support/runtime/exception_libcxxabi.ipp"
-# include "support/runtime/exception_pointer_refcounted.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_refcounted.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_refcounted.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"
More information about the libcxx-commits
mailing list