| 1 | //===----------------------------------------------------------------------===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 |
| 10 | // UNSUPPORTED: no-threads |
| 11 | |
| 12 | // <stdatomic.h> |
| 13 | |
| 14 | // template<class T> |
| 15 | // using std-atomic = std::atomic<T>; // exposition only |
| 16 | // |
| 17 | // #define _Atomic(T) std-atomic<T> |
| 18 | // |
| 19 | // #define ATOMIC_BOOL_LOCK_FREE see below |
| 20 | // #define ATOMIC_CHAR_LOCK_FREE see below |
| 21 | // #define ATOMIC_CHAR16_T_LOCK_FREE see below |
| 22 | // #define ATOMIC_CHAR32_T_LOCK_FREE see below |
| 23 | // #define ATOMIC_WCHAR_T_LOCK_FREE see below |
| 24 | // #define ATOMIC_SHORT_LOCK_FREE see below |
| 25 | // #define ATOMIC_INT_LOCK_FREE see below |
| 26 | // #define ATOMIC_LONG_LOCK_FREE see below |
| 27 | // #define ATOMIC_LLONG_LOCK_FREE see below |
| 28 | // #define ATOMIC_POINTER_LOCK_FREE see below |
| 29 | // |
| 30 | // using std::memory_order // see below |
| 31 | // using std::memory_order_relaxed // see below |
| 32 | // using std::memory_order_consume // see below |
| 33 | // using std::memory_order_acquire // see below |
| 34 | // using std::memory_order_release // see below |
| 35 | // using std::memory_order_acq_rel // see below |
| 36 | // using std::memory_order_seq_cst // see below |
| 37 | // |
| 38 | // using std::atomic_flag // see below |
| 39 | // |
| 40 | // using std::atomic_bool // see below |
| 41 | // using std::atomic_char // see below |
| 42 | // using std::atomic_schar // see below |
| 43 | // using std::atomic_uchar // see below |
| 44 | // using std::atomic_short // see below |
| 45 | // using std::atomic_ushort // see below |
| 46 | // using std::atomic_int // see below |
| 47 | // using std::atomic_uint // see below |
| 48 | // using std::atomic_long // see below |
| 49 | // using std::atomic_ulong // see below |
| 50 | // using std::atomic_llong // see below |
| 51 | // using std::atomic_ullong // see below |
| 52 | // using std::atomic_char8_t // see below |
| 53 | // using std::atomic_char16_t // see below |
| 54 | // using std::atomic_char32_t // see below |
| 55 | // using std::atomic_wchar_t // see below |
| 56 | // using std::atomic_int8_t // see below |
| 57 | // using std::atomic_uint8_t // see below |
| 58 | // using std::atomic_int16_t // see below |
| 59 | // using std::atomic_uint16_t // see below |
| 60 | // using std::atomic_int32_t // see below |
| 61 | // using std::atomic_uint32_t // see below |
| 62 | // using std::atomic_int64_t // see below |
| 63 | // using std::atomic_uint64_t // see below |
| 64 | // using std::atomic_int_least8_t // see below |
| 65 | // using std::atomic_uint_least8_t // see below |
| 66 | // using std::atomic_int_least16_t // see below |
| 67 | // using std::atomic_uint_least16_t // see below |
| 68 | // using std::atomic_int_least32_t // see below |
| 69 | // using std::atomic_uint_least32_t // see below |
| 70 | // using std::atomic_int_least64_t // see below |
| 71 | // using std::atomic_uint_least64_t // see below |
| 72 | // using std::atomic_int_fast8_t // see below |
| 73 | // using std::atomic_uint_fast8_t // see below |
| 74 | // using std::atomic_int_fast16_t // see below |
| 75 | // using std::atomic_uint_fast16_t // see below |
| 76 | // using std::atomic_int_fast32_t // see below |
| 77 | // using std::atomic_uint_fast32_t // see below |
| 78 | // using std::atomic_int_fast64_t // see below |
| 79 | // using std::atomic_uint_fast64_t // see below |
| 80 | // using std::atomic_intptr_t // see below |
| 81 | // using std::atomic_uintptr_t // see below |
| 82 | // using std::atomic_size_t // see below |
| 83 | // using std::atomic_ptrdiff_t // see below |
| 84 | // using std::atomic_intmax_t // see below |
| 85 | // using std::atomic_uintmax_t // see below |
| 86 | // |
| 87 | // using std::atomic_is_lock_free // see below |
| 88 | // using std::atomic_load // see below |
| 89 | // using std::atomic_load_explicit // see below |
| 90 | // using std::atomic_store // see below |
| 91 | // using std::atomic_store_explicit // see below |
| 92 | // using std::atomic_exchange // see below |
| 93 | // using std::atomic_exchange_explicit // see below |
| 94 | // using std::atomic_compare_exchange_strong // see below |
| 95 | // using std::atomic_compare_exchange_strong_explicit // see below |
| 96 | // using std::atomic_compare_exchange_weak // see below |
| 97 | // using std::atomic_compare_exchange_weak_explicit // see below |
| 98 | // using std::atomic_fetch_add // see below |
| 99 | // using std::atomic_fetch_add_explicit // see below |
| 100 | // using std::atomic_fetch_sub // see below |
| 101 | // using std::atomic_fetch_sub_explicit // see below |
| 102 | // using std::atomic_fetch_or // see below |
| 103 | // using std::atomic_fetch_or_explicit // see below |
| 104 | // using std::atomic_fetch_xor // see below |
| 105 | // using std::atomic_fetch_xor_explicit // see below |
| 106 | // using std::atomic_fetch_and // see below |
| 107 | // using std::atomic_fetch_and_explicit // see below |
| 108 | // using std::atomic_flag_test_and_set // see below |
| 109 | // using std::atomic_flag_test_and_set_explicit // see below |
| 110 | // using std::atomic_flag_clear // see below |
| 111 | // using std::atomic_flag_clear_explicit // see below |
| 112 | // |
| 113 | // using std::atomic_thread_fence // see below |
| 114 | // using std::atomic_signal_fence // see below |
| 115 | |
| 116 | #include <stdatomic.h> |
| 117 | #include <cstddef> |
| 118 | #include <cstdint> |
| 119 | #include <type_traits> |
| 120 | |
| 121 | #include "test_macros.h" |
| 122 | |
| 123 | static_assert(std::atomic<bool>::is_always_lock_free == (2 == ATOMIC_BOOL_LOCK_FREE)); |
| 124 | static_assert(std::atomic<char>::is_always_lock_free == (2 == ATOMIC_CHAR_LOCK_FREE)); |
| 125 | static_assert(std::atomic<signed char>::is_always_lock_free == (2 == ATOMIC_CHAR_LOCK_FREE)); |
| 126 | static_assert(std::atomic<unsigned char>::is_always_lock_free == (2 == ATOMIC_CHAR_LOCK_FREE)); |
| 127 | static_assert(std::atomic<char16_t>::is_always_lock_free == (2 == ATOMIC_CHAR16_T_LOCK_FREE)); |
| 128 | static_assert(std::atomic<char32_t>::is_always_lock_free == (2 == ATOMIC_CHAR32_T_LOCK_FREE)); |
| 129 | #ifndef TEST_HAS_NO_WIDE_CHARACTERS |
| 130 | static_assert(std::atomic<wchar_t>::is_always_lock_free == (2 == ATOMIC_WCHAR_T_LOCK_FREE)); |
| 131 | #endif |
| 132 | static_assert(std::atomic<short>::is_always_lock_free == (2 == ATOMIC_SHORT_LOCK_FREE)); |
| 133 | static_assert(std::atomic<unsigned short>::is_always_lock_free == (2 == ATOMIC_SHORT_LOCK_FREE)); |
| 134 | static_assert(std::atomic<int>::is_always_lock_free == (2 == ATOMIC_INT_LOCK_FREE)); |
| 135 | static_assert(std::atomic<unsigned int>::is_always_lock_free == (2 == ATOMIC_INT_LOCK_FREE)); |
| 136 | static_assert(std::atomic<long>::is_always_lock_free == (2 == ATOMIC_LONG_LOCK_FREE)); |
| 137 | static_assert(std::atomic<unsigned long>::is_always_lock_free == (2 == ATOMIC_LONG_LOCK_FREE)); |
| 138 | static_assert(std::atomic<long long>::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE)); |
| 139 | static_assert(std::atomic<unsigned long long>::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE)); |
| 140 | static_assert(std::atomic<void*>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE)); |
| 141 | static_assert(std::atomic<std::nullptr_t>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE)); |
| 142 | |
| 143 | void f() { |
| 144 | static_assert(std::is_same_v<std::atomic<char>, _Atomic(char)>); |
| 145 | static_assert(std::is_same_v<std::atomic<int>, _Atomic(int)>); |
| 146 | static_assert(std::is_same_v<std::atomic<const long>, _Atomic(const long)>); |
| 147 | |
| 148 | static_assert(std::is_same_v<std::memory_order, ::memory_order>); |
| 149 | static_assert(std::memory_order_relaxed == ::memory_order_relaxed); |
| 150 | static_assert(std::memory_order_consume == ::memory_order_consume); |
| 151 | static_assert(std::memory_order_acquire == ::memory_order_acquire); |
| 152 | static_assert(std::memory_order_release == ::memory_order_release); |
| 153 | static_assert(std::memory_order_acq_rel == ::memory_order_acq_rel); |
| 154 | static_assert(std::memory_order_seq_cst == ::memory_order_seq_cst); |
| 155 | |
| 156 | static_assert(std::is_same_v<std::atomic_flag, ::atomic_flag>); |
| 157 | |
| 158 | static_assert(std::is_same_v<std::atomic<bool>, ::atomic_bool>); |
| 159 | static_assert(std::is_same_v<std::atomic<char>, ::atomic_char>); |
| 160 | static_assert(std::is_same_v<std::atomic<signed char>, ::atomic_schar>); |
| 161 | static_assert(std::is_same_v<std::atomic<unsigned char>, ::atomic_uchar>); |
| 162 | static_assert(std::is_same_v<std::atomic<short>, ::atomic_short>); |
| 163 | static_assert(std::is_same_v<std::atomic<unsigned short>, ::atomic_ushort>); |
| 164 | static_assert(std::is_same_v<std::atomic<int>, ::atomic_int>); |
| 165 | static_assert(std::is_same_v<std::atomic<unsigned int>, ::atomic_uint>); |
| 166 | static_assert(std::is_same_v<std::atomic<long>, ::atomic_long>); |
| 167 | static_assert(std::is_same_v<std::atomic<unsigned long>, ::atomic_ulong>); |
| 168 | static_assert(std::is_same_v<std::atomic<long long>, ::atomic_llong>); |
| 169 | static_assert(std::is_same_v<std::atomic<unsigned long long>, ::atomic_ullong>); |
| 170 | |
| 171 | #if _LIBCPP_HAS_CHAR8_T |
| 172 | static_assert(std::is_same_v<std::atomic<char8_t>, ::atomic_char8_t>); |
| 173 | #endif |
| 174 | static_assert(std::is_same_v<std::atomic<char16_t>, ::atomic_char16_t>); |
| 175 | static_assert(std::is_same_v<std::atomic<char32_t>, ::atomic_char32_t>); |
| 176 | #ifndef TEST_HAS_NO_WIDE_CHARACTERS |
| 177 | static_assert(std::is_same_v<std::atomic<wchar_t>, ::atomic_wchar_t>); |
| 178 | #endif |
| 179 | |
| 180 | static_assert(std::is_same_v<std::atomic<int8_t>, ::atomic_int8_t>); |
| 181 | static_assert(std::is_same_v<std::atomic<uint8_t>, ::atomic_uint8_t>); |
| 182 | static_assert(std::is_same_v<std::atomic<int16_t>, ::atomic_int16_t>); |
| 183 | static_assert(std::is_same_v<std::atomic<uint16_t>, ::atomic_uint16_t>); |
| 184 | static_assert(std::is_same_v<std::atomic<int32_t>, ::atomic_int32_t>); |
| 185 | static_assert(std::is_same_v<std::atomic<uint32_t>, ::atomic_uint32_t>); |
| 186 | static_assert(std::is_same_v<std::atomic<int64_t>, ::atomic_int64_t>); |
| 187 | static_assert(std::is_same_v<std::atomic<uint64_t>, ::atomic_uint64_t>); |
| 188 | |
| 189 | static_assert(std::is_same_v<std::atomic<int_least8_t>, ::atomic_int_least8_t>); |
| 190 | static_assert(std::is_same_v<std::atomic<uint_least8_t>, ::atomic_uint_least8_t>); |
| 191 | static_assert(std::is_same_v<std::atomic<int_least16_t>, ::atomic_int_least16_t>); |
| 192 | static_assert(std::is_same_v<std::atomic<uint_least16_t>, ::atomic_uint_least16_t>); |
| 193 | static_assert(std::is_same_v<std::atomic<int_least32_t>, ::atomic_int_least32_t>); |
| 194 | static_assert(std::is_same_v<std::atomic<uint_least32_t>, ::atomic_uint_least32_t>); |
| 195 | static_assert(std::is_same_v<std::atomic<int_least64_t>, ::atomic_int_least64_t>); |
| 196 | static_assert(std::is_same_v<std::atomic<uint_least64_t>, ::atomic_uint_least64_t>); |
| 197 | |
| 198 | static_assert(std::is_same_v<std::atomic<int_fast8_t>, ::atomic_int_fast8_t>); |
| 199 | static_assert(std::is_same_v<std::atomic<uint_fast8_t>, ::atomic_uint_fast8_t>); |
| 200 | static_assert(std::is_same_v<std::atomic<int_fast16_t>, ::atomic_int_fast16_t>); |
| 201 | static_assert(std::is_same_v<std::atomic<uint_fast16_t>, ::atomic_uint_fast16_t>); |
| 202 | static_assert(std::is_same_v<std::atomic<int_fast32_t>, ::atomic_int_fast32_t>); |
| 203 | static_assert(std::is_same_v<std::atomic<uint_fast32_t>, ::atomic_uint_fast32_t>); |
| 204 | static_assert(std::is_same_v<std::atomic<int_fast64_t>, ::atomic_int_fast64_t>); |
| 205 | static_assert(std::is_same_v<std::atomic<uint_fast64_t>, ::atomic_uint_fast64_t>); |
| 206 | |
| 207 | static_assert(std::is_same_v<std::atomic<std::intptr_t>, ::atomic_intptr_t>); |
| 208 | static_assert(std::is_same_v<std::atomic<std::uintptr_t>, ::atomic_uintptr_t>); |
| 209 | static_assert(std::is_same_v<std::atomic<std::size_t>, ::atomic_size_t>); |
| 210 | static_assert(std::is_same_v<std::atomic<std::ptrdiff_t>, ::atomic_ptrdiff_t>); |
| 211 | static_assert(std::is_same_v<std::atomic<std::intmax_t>, ::atomic_intmax_t>); |
| 212 | static_assert(std::is_same_v<std::atomic<std::uintmax_t>, ::atomic_uintmax_t>); |
| 213 | |
| 214 | // Just check that the symbols in the global namespace are visible. |
| 215 | using ::atomic_compare_exchange_strong; |
| 216 | using ::atomic_compare_exchange_strong_explicit; |
| 217 | using ::atomic_compare_exchange_weak; |
| 218 | using ::atomic_compare_exchange_weak_explicit; |
| 219 | using ::atomic_exchange; |
| 220 | using ::atomic_exchange_explicit; |
| 221 | using ::atomic_fetch_add; |
| 222 | using ::atomic_fetch_add_explicit; |
| 223 | using ::atomic_fetch_and; |
| 224 | using ::atomic_fetch_and_explicit; |
| 225 | using ::atomic_fetch_or; |
| 226 | using ::atomic_fetch_or_explicit; |
| 227 | using ::atomic_fetch_sub; |
| 228 | using ::atomic_fetch_sub_explicit; |
| 229 | using ::atomic_fetch_xor; |
| 230 | using ::atomic_fetch_xor_explicit; |
| 231 | using ::atomic_flag_clear; |
| 232 | using ::atomic_flag_clear_explicit; |
| 233 | using ::atomic_flag_test_and_set; |
| 234 | using ::atomic_flag_test_and_set_explicit; |
| 235 | using ::atomic_is_lock_free; |
| 236 | using ::atomic_load; |
| 237 | using ::atomic_load_explicit; |
| 238 | using ::atomic_store; |
| 239 | using ::atomic_store_explicit; |
| 240 | |
| 241 | using ::atomic_signal_fence; |
| 242 | using ::atomic_thread_fence; |
| 243 | } |
| 244 | |