diff --git a/libcxx/docs/Cxx2aStatusPaperStatus.csv b/libcxx/docs/Cxx2aStatusPaperStatus.csv --- a/libcxx/docs/Cxx2aStatusPaperStatus.csv +++ b/libcxx/docs/Cxx2aStatusPaperStatus.csv @@ -133,7 +133,7 @@ "`P1661 `__","LWG","Remove dedicated precalculated hash lookup interface","Cologne","|Nothing To Do|","" "`P1754 `__","LWG","Rename concepts to standard_case for C++20, while we still can","Cologne","|In Progress|","" "","","","","","" -"`P0883 `__","LWG","Fixing Atomic Initialization","Belfast","* *","" +"`P0883 `__","LWG","Fixing Atomic Initialization","Belfast","|Complete|","13.0" "`P1391 `__","LWG","Range constructor for std::string_view","Belfast","* *","" "`P1394 `__","LWG","Range constructor for std::span","Belfast","* *","" "`P1456 `__","LWG","Move-only views","Belfast","* *","" diff --git a/libcxx/include/atomic b/libcxx/include/atomic --- a/libcxx/include/atomic +++ b/libcxx/include/atomic @@ -67,7 +67,8 @@ bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; - atomic() noexcept = default; + atomic() noexcept = default; // until C++20 + constexpr atomic() noexcept(is_nothrow_default_constructible_v); // since C++20 constexpr atomic(T desr) noexcept; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; @@ -201,7 +202,8 @@ bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; - atomic() noexcept = default; + atomic() noexcept = default; // until C++17 + constexpr atomic() noexcept; // since C++17 constexpr atomic(T* desr) noexcept; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; @@ -509,7 +511,8 @@ typedef struct atomic_flag { - atomic_flag() noexcept = default; + atomic_flag() noexcept = default; // until C++17 + constexpr atomic_flag() noexcept; // since C++20 atomic_flag(const atomic_flag&) = delete; atomic_flag& operator=(const atomic_flag&) = delete; atomic_flag& operator=(const atomic_flag&) volatile = delete; @@ -1673,8 +1676,13 @@ _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT {__cxx_atomic_notify_all(&__a_);} +#if _LIBCPP_STD_VER >= 20 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + __atomic_base() _NOEXCEPT : __a_{} {} +#else _LIBCPP_INLINE_VISIBILITY __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT +#endif _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} @@ -1700,8 +1708,15 @@ : public __atomic_base<_Tp, false> { typedef __atomic_base<_Tp, false> __base; + +#if _LIBCPP_STD_VER >= 20 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + __atomic_base() _NOEXCEPT : __base{} {} +#else _LIBCPP_INLINE_VISIBILITY __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT +#endif + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {} @@ -1783,8 +1798,15 @@ typedef __atomic_base<_Tp> __base; typedef _Tp value_type; typedef value_type difference_type; + +#if _LIBCPP_STD_VER >= 20 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + atomic() _NOEXCEPT_(is_nothrow_default_constructible_v<_Tp>) : __base{} {} +#else _LIBCPP_INLINE_VISIBILITY atomic() _NOEXCEPT _LIBCPP_DEFAULT +#endif + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {} @@ -1808,8 +1830,15 @@ typedef __atomic_base<_Tp*> __base; typedef _Tp* value_type; typedef ptrdiff_t difference_type; + +#if _LIBCPP_STD_VER >= 20 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + atomic() _NOEXCEPT : __base{} {} +#else _LIBCPP_INLINE_VISIBILITY atomic() _NOEXCEPT _LIBCPP_DEFAULT +#endif + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {} @@ -2534,8 +2563,13 @@ void notify_all() _NOEXCEPT {__cxx_atomic_notify_all(&__a_);} +#if _LIBCPP_STD_VER >= 20 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + atomic_flag() _NOEXCEPT : __a_{} {} +#else _LIBCPP_INLINE_VISIBILITY atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT +#endif _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION diff --git a/libcxx/test/std/atomics/atomics.types.generic/constexpr_noexcept.pass.cpp b/libcxx/test/std/atomics/atomics.types.generic/constexpr_noexcept.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/atomics/atomics.types.generic/constexpr_noexcept.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-has-no-threads + +#include + +template +constexpr void test() { + [[maybe_unused]] constexpr T a; + static_assert(std::is_nothrow_constructible_v); +} + +struct throwing { + throwing(); +}; + +struct trivial { + int a; +}; + +int main() { + test >(); + test >(); + test >(); + test(); + + static_assert(!std::is_nothrow_constructible_v >); +}