Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 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
2 changes: 1 addition & 1 deletion libcxx/docs/TestingLibcxx.rst
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ Instead use:

.. code-block:: cpp
// UNSUPPORTED: std-at-least-c++26
// REQUIRES: std-at-least-c++26
There is no corresponding ``std-at-most-c++23``. This could be useful when
tests are only valid for a small set of standard versions. For example, a
Expand Down
23 changes: 23 additions & 0 deletions libcxx/include/__exception/exception_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,18 @@
#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 <cstdlib>
#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 @@ -57,6 +62,8 @@ _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_;

Expand All @@ -75,7 +82,15 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
_LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}

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_HIDE_FROM_ABI exception_ptr& operator=(exception_ptr&& __other) _NOEXCEPT {
exception_ptr __tmp(std::move(__other));
std::swap(__tmp, *this);
return *this;
}
~exception_ptr() _NOEXCEPT;

_LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __ptr_ != nullptr; }
Expand All @@ -88,10 +103,16 @@ 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 @@ -201,4 +222,6 @@ _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
1 change: 1 addition & 0 deletions libcxx/modules/std/exception.inc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export namespace std {
using std::rethrow_exception;
using std::rethrow_if_nested;
using std::set_terminate;
using std::swap;
Copy link
Member Author

@vogelsgesang vogelsgesang Oct 31, 2025

Choose a reason for hiding this comment

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

I had to add std::swap to this list since otherwise
the test cases libcxx/module_std.gen.py/module_std.sh.cpp and libcxx/module_std_compat.gen.py/module_std_compat.sh.cpp failed.

I don't quite understand the modules build, though. Is this correct?

(Note that we now have both a std::swap and a std::_LIBCPP_ABI_NAMESPACE::swap because exception_ptr is in the unversioned namespace while the normal swap is in the versioned namespace. Not sure if that matters. I hope not 🤞 )

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't quite understand how these tests work either. I'm happy if the CI is happy here.

Copy link
Member Author

Choose a reason for hiding this comment

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

The CI was indeed green 🙂
I merged this (after removing the documentation update from this PR)
Moving on to #165909

using std::terminate;
using std::terminate_handler;
using std::throw_with_nested;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

#include <exception>
#include <cassert>
#include <type_traits>

#include "test_macros.h"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: no-exceptions, c++03

// <exception>

// typedef unspecified exception_ptr;

// Test the move assignment of exception_ptr

#include <exception>
#include <utility>
#include <cassert>

#include "test_macros.h"

int main(int, char**) {
std::exception_ptr p = std::make_exception_ptr(42);
std::exception_ptr p2{p};
assert(p2 == p);
// Under test: the move assignment
std::exception_ptr p3;
p3 = std::move(p2);
assert(p3 == p);
// `p2` was moved from. In libc++ it will be nullptr, but
// this is not guaranteed by the standard.
#if defined(_LIBCPP_VERSION) && !defined(_LIBCPP_ABI_MICROSOFT)
assert(p2 == nullptr);
assert(p2 == nullptr);
#endif

try {
std::rethrow_exception(p3);
} catch (int e) {
assert(e == 42);
}

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: no-exceptions, c++03

// <exception>

// typedef unspecified exception_ptr;

// Test the move constructor of exception_ptr

#include <exception>
#include <utility>
#include <cassert>

#include "test_macros.h"

int main(int, char**) {
std::exception_ptr p = std::make_exception_ptr(42);
std::exception_ptr p2{p};
assert(p2 == p);
// Under test: The move constructor
std::exception_ptr p3{std::move(p2)};
assert(p3 == p);
// `p2` was moved from. In libc++ it will be nullptr, but
// this is not guaranteed by the standard.
#if defined(_LIBCPP_VERSION) && !defined(_LIBCPP_ABI_MICROSOFT)
assert(p2 == nullptr);
#endif

try {
std::rethrow_exception(p3);
} catch (int e) {
assert(e == 42);
}

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: no-exceptions

// <exception>

// typedef unspecified exception_ptr;

// Test swapping of exception_ptr

#include <exception>
#include <utility>
#include <cassert>

#include "test_macros.h"

int main(int, char**) {
std::exception_ptr p21 = std::make_exception_ptr(42);
std::exception_ptr p42 = std::make_exception_ptr(21);
std::swap(p42, p21);

try {
std::rethrow_exception(p21);
} catch (int e) {
assert(e == 21);
}
try {
std::rethrow_exception(p42);
} catch (int e) {
assert(e == 42);
}

return 0;
}
Loading