diff --git a/libcxx/docs/Cxx2bStatusPaperStatus.csv b/libcxx/docs/Cxx2bStatusPaperStatus.csv --- a/libcxx/docs/Cxx2bStatusPaperStatus.csv +++ b/libcxx/docs/Cxx2bStatusPaperStatus.csv @@ -1,6 +1,6 @@ "Paper #","Group","Paper Name","Meeting","Status","First released version" "`P0881R7 `__","LWG","A Proposal to add stacktrace library","Autumn 2020","","" -"`P0943R6 `__","LWG","Support C atomics in C++","Autumn 2020","","" +"`P0943R6 `__","LWG","Support C atomics in C++","Autumn 2020","|Complete|","13.0" "`P1048R1 `__","LWG","A proposal for a type trait to detect scoped enumerations","Autumn 2020","|Complete|","12.0" "`P1679R3 `__","LWG","string contains function","Autumn 2020","|Complete|","12.0" "","","","","","" diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -298,7 +298,7 @@ ------------------------------------------------- ----------------- ``__cpp_lib_stacktrace`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_stdatomic_h`` *unimplemented* + ``__cpp_lib_stdatomic_h`` ``202011L`` ------------------------------------------------- ----------------- ``__cpp_lib_string_contains`` ``202011L`` ================================================= ================= diff --git a/libcxx/include/stdatomic.h b/libcxx/include/stdatomic.h new file mode 100644 --- /dev/null +++ b/libcxx/include/stdatomic.h @@ -0,0 +1,231 @@ +// -*- C++ -*- +//===--------------------------- wchar.h ----------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#if !defined(_LIBCPP_STDATOMIC_H) +#define _LIBCPP_STDATOMIC_H + +/* + stdatomic.h synopsis + +template + using std-atomic = std::atomic; // exposition only + +#define _Atomic(T) std-atomic + +#define ATOMIC_BOOL_LOCK_FREE see below +#define ATOMIC_CHAR_LOCK_FREE see below +#define ATOMIC_CHAR16_T_LOCK_FREE see below +#define ATOMIC_CHAR32_T_LOCK_FREE see below +#define ATOMIC_WCHAR_T_LOCK_FREE see below +#define ATOMIC_SHORT_LOCK_FREE see below +#define ATOMIC_INT_LOCK_FREE see below +#define ATOMIC_LONG_LOCK_FREE see below +#define ATOMIC_LLONG_LOCK_FREE see below +#define ATOMIC_POINTER_LOCK_FREE see below + +using std::memory_order // see below +using std::memory_order_relaxed // see below +using std::memory_order_consume // see below +using std::memory_order_acquire // see below +using std::memory_order_release // see below +using std::memory_order_acq_rel // see below +using std::memory_order_seq_cst // see below + +using std::atomic_flag // see below + +using std::atomic_bool // see below +using std::atomic_char // see below +using std::atomic_schar // see below +using std::atomic_uchar // see below +using std::atomic_short // see below +using std::atomic_ushort // see below +using std::atomic_int // see below +using std::atomic_uint // see below +using std::atomic_long // see below +using std::atomic_ulong // see below +using std::atomic_llong // see below +using std::atomic_ullong // see below +using std::atomic_char8_t // see below +using std::atomic_char16_t // see below +using std::atomic_char32_t // see below +using std::atomic_wchar_t // see below +using std::atomic_int8_t // see below +using std::atomic_uint8_t // see below +using std::atomic_int16_t // see below +using std::atomic_uint16_t // see below +using std::atomic_int32_t // see below +using std::atomic_uint32_t // see below +using std::atomic_int64_t // see below +using std::atomic_uint64_t // see below +using std::atomic_int_least8_t // see below +using std::atomic_uint_least8_t // see below +using std::atomic_int_least16_t // see below +using std::atomic_uint_least16_t // see below +using std::atomic_int_least32_t // see below +using std::atomic_uint_least32_t // see below +using std::atomic_int_least64_t // see below +using std::atomic_uint_least64_t // see below +using std::atomic_int_fast8_t // see below +using std::atomic_uint_fast8_t // see below +using std::atomic_int_fast16_t // see below +using std::atomic_uint_fast16_t // see below +using std::atomic_int_fast32_t // see below +using std::atomic_uint_fast32_t // see below +using std::atomic_int_fast64_t // see below +using std::atomic_uint_fast64_t // see below +using std::atomic_intptr_t // see below +using std::atomic_uintptr_t // see below +using std::atomic_size_t // see below +using std::atomic_ptrdiff_t // see below +using std::atomic_intmax_t // see below +using std::atomic_uintmax_t // see below + +using std::atomic_is_lock_free // see below +using std::atomic_load // see below +using std::atomic_load_explicit // see below +using std::atomic_store // see below +using std::atomic_store_explicit // see below +using std::atomic_exchange // see below +using std::atomic_exchange_explicit // see below +using std::atomic_compare_exchange_strong // see below +using std::atomic_compare_exchange_strong_explicit // see below +using std::atomic_compare_exchange_weak // see below +using std::atomic_compare_exchange_weak_explicit // see below +using std::atomic_fetch_add // see below +using std::atomic_fetch_add_explicit // see below +using std::atomic_fetch_sub // see below +using std::atomic_fetch_sub_explicit // see below +using std::atomic_fetch_or // see below +using std::atomic_fetch_or_explicit // see below +using std::atomic_fetch_and // see below +using std::atomic_fetch_and_explicit // see below +using std::atomic_flag_test_and_set // see below +using std::atomic_flag_test_and_set_explicit // see below +using std::atomic_flag_clear // see below +using std::atomic_flag_clear_explicit // see below + +using std::atomic_thread_fence // see below +using std::atomic_signal_fence // see below + +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifdef __cplusplus + +#include +#include + +#ifdef _Atomic +#undef _Atomic(T) +#endif + +#define _Atomic(T) _VSTD::atomic + +using _VSTD::memory_order; +using _VSTD::memory_order_relaxed; +using _VSTD::memory_order_consume; +using _VSTD::memory_order_acquire; +using _VSTD::memory_order_release; +using _VSTD::memory_order_acq_rel; +using _VSTD::memory_order_seq_cst; + +using _VSTD::atomic_flag; + +using _VSTD::atomic_bool; +using _VSTD::atomic_char; +using _VSTD::atomic_schar; +using _VSTD::atomic_uchar; +using _VSTD::atomic_short; +using _VSTD::atomic_ushort; +using _VSTD::atomic_int; +using _VSTD::atomic_uint; +using _VSTD::atomic_long; +using _VSTD::atomic_ulong; +using _VSTD::atomic_llong; +using _VSTD::atomic_ullong; +#ifndef _LIBCPP_NO_HAS_CHAR8_T +using _VSTD::atomic_char8_t; +#endif +using _VSTD::atomic_char16_t; +using _VSTD::atomic_char32_t; +using _VSTD::atomic_wchar_t; + +using _VSTD::atomic_int8_t; +using _VSTD::atomic_uint8_t; +using _VSTD::atomic_int16_t; +using _VSTD::atomic_uint16_t; +using _VSTD::atomic_int32_t; +using _VSTD::atomic_uint32_t; +using _VSTD::atomic_int64_t; +using _VSTD::atomic_uint64_t; + +using _VSTD::atomic_int_least8_t; +using _VSTD::atomic_uint_least8_t; +using _VSTD::atomic_int_least16_t; +using _VSTD::atomic_uint_least16_t; +using _VSTD::atomic_int_least32_t; +using _VSTD::atomic_uint_least32_t; +using _VSTD::atomic_int_least64_t; +using _VSTD::atomic_uint_least64_t; + +using _VSTD::atomic_int_fast8_t; +using _VSTD::atomic_uint_fast8_t; +using _VSTD::atomic_int_fast16_t; +using _VSTD::atomic_uint_fast16_t; +using _VSTD::atomic_int_fast32_t; +using _VSTD::atomic_uint_fast32_t; +using _VSTD::atomic_int_fast64_t; +using _VSTD::atomic_uint_fast64_t; + +using _VSTD::atomic_intptr_t; +using _VSTD::atomic_uintptr_t; +using _VSTD::atomic_size_t; +using _VSTD::atomic_ptrdiff_t; +using _VSTD::atomic_intmax_t; +using _VSTD::atomic_uintmax_t; + +using _VSTD::atomic_compare_exchange_strong; +using _VSTD::atomic_compare_exchange_strong_explicit; +using _VSTD::atomic_compare_exchange_weak; +using _VSTD::atomic_compare_exchange_weak_explicit; +using _VSTD::atomic_exchange; +using _VSTD::atomic_exchange_explicit; +using _VSTD::atomic_fetch_add; +using _VSTD::atomic_fetch_add_explicit; +using _VSTD::atomic_fetch_and; +using _VSTD::atomic_fetch_and_explicit; +using _VSTD::atomic_fetch_or; +using _VSTD::atomic_fetch_or_explicit; +using _VSTD::atomic_fetch_sub; +using _VSTD::atomic_fetch_sub_explicit; +using _VSTD::atomic_flag_clear; +using _VSTD::atomic_flag_clear_explicit; +using _VSTD::atomic_flag_test_and_set; +using _VSTD::atomic_flag_test_and_set_explicit; +using _VSTD::atomic_is_lock_free; +using _VSTD::atomic_load; +using _VSTD::atomic_load_explicit; +using _VSTD::atomic_store; +using _VSTD::atomic_store_explicit; + +using _VSTD::atomic_signal_fence; +using _VSTD::atomic_thread_fence; + +#else // __cplusplus + +#include_next + +#endif // __cplusplus + +#endif // _LIBCPP_STDATOMIC_H diff --git a/libcxx/include/version b/libcxx/include/version --- a/libcxx/include/version +++ b/libcxx/include/version @@ -361,7 +361,7 @@ #if _LIBCPP_STD_VER > 20 # define __cpp_lib_is_scoped_enum 202011L // # define __cpp_lib_stacktrace 202011L -// # define __cpp_lib_stdatomic_h 202011L +# define __cpp_lib_stdatomic_h 202011L # define __cpp_lib_string_contains 202011L #endif diff --git a/libcxx/test/libcxx/double_include.sh.cpp b/libcxx/test/libcxx/double_include.sh.cpp --- a/libcxx/test/libcxx/double_include.sh.cpp +++ b/libcxx/test/libcxx/double_include.sh.cpp @@ -161,6 +161,9 @@ # include #endif #include +#ifndef _LIBCPP_HAS_NO_THREADS +# include +#endif #include #include #include diff --git a/libcxx/test/libcxx/min_max_macros.compile.pass.cpp b/libcxx/test/libcxx/min_max_macros.compile.pass.cpp --- a/libcxx/test/libcxx/min_max_macros.compile.pass.cpp +++ b/libcxx/test/libcxx/min_max_macros.compile.pass.cpp @@ -246,6 +246,10 @@ #endif #include TEST_MACROS(); +#ifndef _LIBCPP_HAS_NO_THREADS +# include +TEST_MACROS(); +#endif #include TEST_MACROS(); #include diff --git a/libcxx/test/libcxx/no_assert_include.compile.pass.cpp b/libcxx/test/libcxx/no_assert_include.compile.pass.cpp --- a/libcxx/test/libcxx/no_assert_include.compile.pass.cpp +++ b/libcxx/test/libcxx/no_assert_include.compile.pass.cpp @@ -154,6 +154,9 @@ # include #endif #include +#ifndef _LIBCPP_HAS_NO_THREADS +# include +#endif #include #include #include diff --git a/libcxx/test/std/atomics/stdatomic.h.syn/types.pass.cpp b/libcxx/test/std/atomics/stdatomic.h.syn/types.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/atomics/stdatomic.h.syn/types.pass.cpp @@ -0,0 +1,238 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++2a +// UNSUPPORTED: libcpp-has-no-threads + +// + +// template +// using std-atomic = std::atomic; // exposition only +// +// #define _Atomic(T) std-atomic +// +// #define ATOMIC_BOOL_LOCK_FREE see below +// #define ATOMIC_CHAR_LOCK_FREE see below +// TODO: No ATOMIC_CHAR8_T_LOCK_FREE, but atomic_char8_t is present in synopis?? NB that atomic_char8_t is not in C11. See http://eel.is/c++draft/stdatomic.h.syn. +// #define ATOMIC_CHAR16_T_LOCK_FREE see below +// #define ATOMIC_CHAR32_T_LOCK_FREE see below +// #define ATOMIC_WCHAR_T_LOCK_FREE see below +// #define ATOMIC_SHORT_LOCK_FREE see below +// #define ATOMIC_INT_LOCK_FREE see below +// #define ATOMIC_LONG_LOCK_FREE see below +// #define ATOMIC_LLONG_LOCK_FREE see below +// #define ATOMIC_POINTER_LOCK_FREE see below +// +// using std::memory_order // see below +// using std::memory_order_relaxed // see below +// using std::memory_order_consume // see below +// using std::memory_order_acquire // see below +// using std::memory_order_release // see below +// using std::memory_order_acq_rel // see below +// using std::memory_order_seq_cst // see below +// +// using std::atomic_flag // see below +// +// using std::atomic_bool // see below +// using std::atomic_char // see below +// using std::atomic_schar // see below +// using std::atomic_uchar // see below +// using std::atomic_short // see below +// using std::atomic_ushort // see below +// using std::atomic_int // see below +// using std::atomic_uint // see below +// using std::atomic_long // see below +// using std::atomic_ulong // see below +// using std::atomic_llong // see below +// using std::atomic_ullong // see below +// using std::atomic_char8_t // see below +// using std::atomic_char16_t // see below +// using std::atomic_char32_t // see below +// using std::atomic_wchar_t // see below +// using std::atomic_int8_t // see below +// using std::atomic_uint8_t // see below +// using std::atomic_int16_t // see below +// using std::atomic_uint16_t // see below +// using std::atomic_int32_t // see below +// using std::atomic_uint32_t // see below +// using std::atomic_int64_t // see below +// using std::atomic_uint64_t // see below +// using std::atomic_int_least8_t // see below +// using std::atomic_uint_least8_t // see below +// using std::atomic_int_least16_t // see below +// using std::atomic_uint_least16_t // see below +// using std::atomic_int_least32_t // see below +// using std::atomic_uint_least32_t // see below +// using std::atomic_int_least64_t // see below +// using std::atomic_uint_least64_t // see below +// using std::atomic_int_fast8_t // see below +// using std::atomic_uint_fast8_t // see below +// using std::atomic_int_fast16_t // see below +// using std::atomic_uint_fast16_t // see below +// using std::atomic_int_fast32_t // see below +// using std::atomic_uint_fast32_t // see below +// using std::atomic_int_fast64_t // see below +// using std::atomic_uint_fast64_t // see below +// using std::atomic_intptr_t // see below +// using std::atomic_uintptr_t // see below +// using std::atomic_size_t // see below +// using std::atomic_ptrdiff_t // see below +// using std::atomic_intmax_t // see below +// using std::atomic_uintmax_t // see below +// +// using std::atomic_is_lock_free // see below +// using std::atomic_load // see below +// using std::atomic_load_explicit // see below +// using std::atomic_store // see below +// using std::atomic_store_explicit // see below +// using std::atomic_exchange // see below +// using std::atomic_exchange_explicit // see below +// using std::atomic_compare_exchange_strong // see below +// using std::atomic_compare_exchange_strong_explicit // see below +// using std::atomic_compare_exchange_weak // see below +// using std::atomic_compare_exchange_weak_explicit // see below +// using std::atomic_fetch_add // see below +// using std::atomic_fetch_add_explicit // see below +// using std::atomic_fetch_sub // see below +// using std::atomic_fetch_sub_explicit // see below +// using std::atomic_fetch_or // see below +// using std::atomic_fetch_or_explicit // see below +// using std::atomic_fetch_and // see below +// using std::atomic_fetch_and_explicit // see below +// using std::atomic_flag_test_and_set // see below +// using std::atomic_flag_test_and_set_explicit // see below +// using std::atomic_flag_clear // see below +// using std::atomic_flag_clear_explicit // see below +// +// using std::atomic_thread_fence // see below +// using std::atomic_signal_fence // see below + +#include +#include + +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_BOOL_LOCK_FREE)); +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_CHAR_LOCK_FREE)); +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_CHAR_LOCK_FREE)); +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_CHAR_LOCK_FREE)); +#ifndef _LIBCPP_NO_HAS_CHAR8_T +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_CHAR8_T_LOCK_FREE)); +#endif +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_CHAR16_T_LOCK_FREE)); +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_CHAR32_T_LOCK_FREE)); +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_WCHAR_T_LOCK_FREE)); +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_SHORT_LOCK_FREE)); +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_SHORT_LOCK_FREE)); +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_INT_LOCK_FREE)); +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_INT_LOCK_FREE)); +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_LONG_LOCK_FREE)); +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_LONG_LOCK_FREE)); +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE)); +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE)); +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE)); +static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE)); + +int main(int, char**) +{ + static_assert(std::is_same_v, _Atomic(char)>); + static_assert(std::is_same_v, _Atomic(int)>); + static_assert(std::is_same_v, _Atomic(const long)>); + + static_assert(std::is_same_v); + static_assert(std::memory_order_relaxed == ::memory_order_relaxed); + static_assert(std::memory_order_consume == ::memory_order_consume); + static_assert(std::memory_order_acquire == ::memory_order_acquire); + static_assert(std::memory_order_release == ::memory_order_release); + static_assert(std::memory_order_acq_rel == ::memory_order_acq_rel); + static_assert(std::memory_order_seq_cst == ::memory_order_seq_cst); + + static_assert((std::is_same_v)); + + static_assert((std::is_same_v, ::atomic_bool>)); + static_assert((std::is_same_v, ::atomic_char>)); + static_assert((std::is_same_v, ::atomic_schar>)); + static_assert((std::is_same_v, ::atomic_uchar>)); + static_assert((std::is_same_v, ::atomic_short>)); + static_assert((std::is_same_v, ::atomic_ushort>)); + static_assert((std::is_same_v, ::atomic_int>)); + static_assert((std::is_same_v, ::atomic_uint>)); + static_assert((std::is_same_v, ::atomic_long>)); + static_assert((std::is_same_v, ::atomic_ulong>)); + static_assert((std::is_same_v, ::atomic_llong>)); + static_assert((std::is_same_v, ::atomic_ullong>)); + +#ifndef _LIBCPP_NO_HAS_CHAR8_T + static_assert((std::is_same_v, ::atomic_char8_t>)); +#endif + static_assert((std::is_same_v, ::atomic_char16_t>)); + static_assert((std::is_same_v, ::atomic_char32_t>)); + static_assert((std::is_same_v, ::atomic_wchar_t>)); + + static_assert((std::is_same_v, ::atomic_int8_t>)); + static_assert((std::is_same_v, ::atomic_uint8_t>)); + static_assert((std::is_same_v, ::atomic_int16_t>)); + static_assert((std::is_same_v, ::atomic_uint16_t>)); + static_assert((std::is_same_v, ::atomic_int32_t>)); + static_assert((std::is_same_v, ::atomic_uint32_t>)); + static_assert((std::is_same_v, ::atomic_int64_t>)); + static_assert((std::is_same_v, ::atomic_uint64_t>)); + + static_assert((std::is_same_v, ::atomic_int_least8_t>)); + static_assert((std::is_same_v, ::atomic_uint_least8_t>)); + static_assert((std::is_same_v, ::atomic_int_least16_t>)); + static_assert((std::is_same_v, ::atomic_uint_least16_t>)); + static_assert((std::is_same_v, ::atomic_int_least32_t>)); + static_assert((std::is_same_v, ::atomic_uint_least32_t>)); + static_assert((std::is_same_v, ::atomic_int_least64_t>)); + static_assert((std::is_same_v, ::atomic_uint_least64_t>)); + + static_assert((std::is_same_v, ::atomic_int_fast8_t>)); + static_assert((std::is_same_v, ::atomic_uint_fast8_t>)); + static_assert((std::is_same_v, ::atomic_int_fast16_t>)); + static_assert((std::is_same_v, ::atomic_uint_fast16_t>)); + static_assert((std::is_same_v, ::atomic_int_fast32_t>)); + static_assert((std::is_same_v, ::atomic_uint_fast32_t>)); + static_assert((std::is_same_v, ::atomic_int_fast64_t>)); + static_assert((std::is_same_v, ::atomic_uint_fast64_t>)); + + static_assert((std::is_same_v, ::atomic_intptr_t>)); + static_assert((std::is_same_v, ::atomic_uintptr_t>)); + static_assert((std::is_same_v, ::atomic_size_t>)); + static_assert((std::is_same_v, ::atomic_ptrdiff_t>)); + static_assert((std::is_same_v, ::atomic_intmax_t>)); + static_assert((std::is_same_v, ::atomic_uintmax_t>)); + + // Just check that the symbols in the global namespace are visible. + using ::atomic_compare_exchange_strong; + using ::atomic_compare_exchange_strong_explicit; + using ::atomic_compare_exchange_weak; + using ::atomic_compare_exchange_weak_explicit; + using ::atomic_exchange; + using ::atomic_exchange_explicit; + using ::atomic_fetch_add; + using ::atomic_fetch_add_explicit; + using ::atomic_fetch_and; + using ::atomic_fetch_and_explicit; + using ::atomic_fetch_or; + using ::atomic_fetch_or_explicit; + using ::atomic_fetch_sub; + using ::atomic_fetch_sub_explicit; + using ::atomic_flag_clear; + using ::atomic_flag_clear_explicit; + using ::atomic_flag_test_and_set; + using ::atomic_flag_test_and_set_explicit; + using ::atomic_is_lock_free; + using ::atomic_load; + using ::atomic_load_explicit; + using ::atomic_store; + using ::atomic_store_explicit; + + using ::atomic_signal_fence; + using ::atomic_thread_fence; + + return 0; +} diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/stdatomic.h.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/stdatomic.h.version.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/stdatomic.h.version.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// WARNING: This test was generated by generate_feature_test_macro_components.py +// and should not be edited manually. +// +// clang-format off + +// + +// Test the feature test macros defined by + +/* Constant Value + __cpp_lib_stdatomic_h 202011L [C++2b] +*/ + +#include +#include "test_macros.h" + +#if TEST_STD_VER < 14 + +# ifdef __cpp_lib_stdatomic_h +# error "__cpp_lib_stdatomic_h should not be defined before c++2b" +# endif + +#elif TEST_STD_VER == 14 + +# ifdef __cpp_lib_stdatomic_h +# error "__cpp_lib_stdatomic_h should not be defined before c++2b" +# endif + +#elif TEST_STD_VER == 17 + +# ifdef __cpp_lib_stdatomic_h +# error "__cpp_lib_stdatomic_h should not be defined before c++2b" +# endif + +#elif TEST_STD_VER == 20 + +# ifdef __cpp_lib_stdatomic_h +# error "__cpp_lib_stdatomic_h should not be defined before c++2b" +# endif + +#elif TEST_STD_VER > 20 + +# ifndef __cpp_lib_stdatomic_h +# error "__cpp_lib_stdatomic_h should be defined in c++2b" +# endif +# if __cpp_lib_stdatomic_h != 202011L +# error "__cpp_lib_stdatomic_h should have the value 202011L in c++2b" +# endif + +#endif // TEST_STD_VER > 20 + +int main(int, char**) { return 0; } 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 @@ -4381,17 +4381,11 @@ # error "__cpp_lib_starts_ends_with should have the value 201711L in c++2b" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_stdatomic_h -# error "__cpp_lib_stdatomic_h should be defined in c++2b" -# endif -# if __cpp_lib_stdatomic_h != 202011L -# error "__cpp_lib_stdatomic_h should have the value 202011L in c++2b" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_stdatomic_h -# error "__cpp_lib_stdatomic_h should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_stdatomic_h +# error "__cpp_lib_stdatomic_h should be defined in c++2b" +# endif +# if __cpp_lib_stdatomic_h != 202011L +# error "__cpp_lib_stdatomic_h should have the value 202011L in c++2b" # endif # ifndef __cpp_lib_string_contains 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 @@ -558,7 +558,6 @@ "name": "__cpp_lib_stdatomic_h", "values": { "c++2b": 202011 }, "headers": ["stdatomic.h"], - "unimplemented": True, }, { "name": "__cpp_lib_string_contains", "values": { "c++2b": 202011 }, diff --git a/libcxx/utils/generate_header_tests.py b/libcxx/utils/generate_header_tests.py --- a/libcxx/utils/generate_header_tests.py +++ b/libcxx/utils/generate_header_tests.py @@ -28,6 +28,7 @@ "mutex": ["ifndef _LIBCPP_HAS_NO_THREADS"], "shared_mutex": ["ifndef _LIBCPP_HAS_NO_THREADS"], "semaphore": ["ifndef _LIBCPP_HAS_NO_THREADS"], + "stdatomic.h": ["ifndef _LIBCPP_HAS_NO_THREADS"], "thread": ["ifndef _LIBCPP_HAS_NO_THREADS"], "filesystem": ["ifndef _LIBCPP_HAS_NO_FILESYSTEM_LIBRARY"],