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/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -182,7 +182,7 @@ ------------------------------------------------- ----------------- ``__cpp_lib_atomic_shared_ptr`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_atomic_value_initialization`` *unimplemented* + ``__cpp_lib_atomic_value_initialization`` ``201911L`` ------------------------------------------------- ----------------- ``__cpp_lib_atomic_wait`` ``201907L`` ------------------------------------------------- ----------------- 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,7 @@ bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; - atomic() noexcept = default; + constexpr atomic() noexcept = default; // constexpr since C++20 constexpr atomic(T* desr) noexcept; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; @@ -509,7 +510,7 @@ typedef struct atomic_flag { - atomic_flag() noexcept = default; + constexpr atomic_flag() noexcept = default; // constexpr 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 +1674,13 @@ _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT {__cxx_atomic_notify_all(&__a_);} +#if _LIBCPP_STD_VER > 17 + _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 +1706,15 @@ : public __atomic_base<_Tp, false> { typedef __atomic_base<_Tp, false> __base; + +#if _LIBCPP_STD_VER > 17 + _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 +1796,15 @@ typedef __atomic_base<_Tp> __base; typedef _Tp value_type; typedef value_type difference_type; + +#if _LIBCPP_STD_VER > 17 + _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 +1828,15 @@ typedef __atomic_base<_Tp*> __base; typedef _Tp* value_type; typedef ptrdiff_t difference_type; + +#if _LIBCPP_STD_VER > 17 + _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) {} @@ -1885,7 +1912,7 @@ // atomic_init template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY void atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT { @@ -1893,7 +1920,7 @@ } template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY void atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT { @@ -2534,8 +2561,13 @@ void notify_all() _NOEXCEPT {__cxx_atomic_notify_all(&__a_);} +#if _LIBCPP_STD_VER > 17 + _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/include/version b/libcxx/include/version --- a/libcxx/include/version +++ b/libcxx/include/version @@ -283,7 +283,7 @@ // # define __cpp_lib_atomic_shared_ptr 201711L # endif # if !defined(_LIBCPP_HAS_NO_THREADS) -// # define __cpp_lib_atomic_value_initialization 201911L +# define __cpp_lib_atomic_value_initialization 201911L # endif # if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait) # define __cpp_lib_atomic_wait 201907L 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,37 @@ +//===----------------------------------------------------------------------===// +// +// 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 bool test() { + [[maybe_unused]] constexpr T a; + static_assert(std::is_nothrow_constructible_v); + return true; +} + +struct throwing { + throwing() {} +}; + +struct trivial { + int a; +}; + +int main() { + static_assert(test>()); + static_assert(test>()); + static_assert(test>()); + static_assert(test>()); + static_assert(test()); + + static_assert(!std::is_nothrow_constructible_v>); +} diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp @@ -235,16 +235,16 @@ # endif # endif -# if !defined(_LIBCPP_VERSION) +# if !defined(_LIBCPP_HAS_NO_THREADS) # ifndef __cpp_lib_atomic_value_initialization # error "__cpp_lib_atomic_value_initialization should be defined in c++20" # endif # if __cpp_lib_atomic_value_initialization != 201911L # error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++20" # endif -# else // _LIBCPP_VERSION +# else # ifdef __cpp_lib_atomic_value_initialization -# error "__cpp_lib_atomic_value_initialization should not be defined because it is unimplemented in libc++!" +# error "__cpp_lib_atomic_value_initialization should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!" # endif # endif @@ -354,16 +354,16 @@ # endif # endif -# if !defined(_LIBCPP_VERSION) +# if !defined(_LIBCPP_HAS_NO_THREADS) # ifndef __cpp_lib_atomic_value_initialization # error "__cpp_lib_atomic_value_initialization should be defined in c++2b" # endif # if __cpp_lib_atomic_value_initialization != 201911L # error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++2b" # endif -# else // _LIBCPP_VERSION +# else # ifdef __cpp_lib_atomic_value_initialization -# error "__cpp_lib_atomic_value_initialization should not be defined because it is unimplemented in libc++!" +# error "__cpp_lib_atomic_value_initialization should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!" # endif # endif diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp @@ -307,16 +307,16 @@ # endif # endif -# if !defined(_LIBCPP_VERSION) +# if !defined(_LIBCPP_HAS_NO_THREADS) # ifndef __cpp_lib_atomic_value_initialization # error "__cpp_lib_atomic_value_initialization should be defined in c++20" # endif # if __cpp_lib_atomic_value_initialization != 201911L # error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++20" # endif -# else // _LIBCPP_VERSION +# else # ifdef __cpp_lib_atomic_value_initialization -# error "__cpp_lib_atomic_value_initialization should not be defined because it is unimplemented in libc++!" +# error "__cpp_lib_atomic_value_initialization should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!" # endif # endif @@ -457,16 +457,16 @@ # endif # endif -# if !defined(_LIBCPP_VERSION) +# if !defined(_LIBCPP_HAS_NO_THREADS) # ifndef __cpp_lib_atomic_value_initialization # error "__cpp_lib_atomic_value_initialization should be defined in c++2b" # endif # if __cpp_lib_atomic_value_initialization != 201911L # error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++2b" # endif -# else // _LIBCPP_VERSION +# else # ifdef __cpp_lib_atomic_value_initialization -# error "__cpp_lib_atomic_value_initialization should not be defined because it is unimplemented in libc++!" +# error "__cpp_lib_atomic_value_initialization should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!" # endif # endif diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp @@ -2242,16 +2242,16 @@ # endif # endif -# if !defined(_LIBCPP_VERSION) +# if !defined(_LIBCPP_HAS_NO_THREADS) # ifndef __cpp_lib_atomic_value_initialization # error "__cpp_lib_atomic_value_initialization should be defined in c++20" # endif # if __cpp_lib_atomic_value_initialization != 201911L # error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++20" # endif -# else // _LIBCPP_VERSION +# else # ifdef __cpp_lib_atomic_value_initialization -# error "__cpp_lib_atomic_value_initialization should not be defined because it is unimplemented in libc++!" +# error "__cpp_lib_atomic_value_initialization should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!" # endif # endif @@ -3423,16 +3423,16 @@ # endif # endif -# if !defined(_LIBCPP_VERSION) +# if !defined(_LIBCPP_HAS_NO_THREADS) # ifndef __cpp_lib_atomic_value_initialization # error "__cpp_lib_atomic_value_initialization should be defined in c++2b" # endif # if __cpp_lib_atomic_value_initialization != 201911L # error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++2b" # endif -# else // _LIBCPP_VERSION +# else # ifdef __cpp_lib_atomic_value_initialization -# error "__cpp_lib_atomic_value_initialization should not be defined because it is unimplemented in libc++!" +# error "__cpp_lib_atomic_value_initialization should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!" # endif # endif diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -138,7 +138,6 @@ "headers": ["atomic", "memory"], "test_suite_guard": "!defined(_LIBCPP_HAS_NO_THREADS)", "libcxx_guard": "!defined(_LIBCPP_HAS_NO_THREADS)", - "unimplemented": True, }, { "name": "__cpp_lib_atomic_wait", "values": { "c++20": 201907 },