diff options
Diffstat (limited to 'test/std/atomics')
58 files changed, 3587 insertions, 0 deletions
diff --git a/test/std/atomics/atomics.fences/atomic_signal_fence.pass.cpp b/test/std/atomics/atomics.fences/atomic_signal_fence.pass.cpp new file mode 100644 index 0000000000000..aec060c4d5f2c --- /dev/null +++ b/test/std/atomics/atomics.fences/atomic_signal_fence.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// void atomic_signal_fence(memory_order m); + +#include <atomic> + +int main() +{ + std::atomic_signal_fence(std::memory_order_seq_cst); +} diff --git a/test/std/atomics/atomics.fences/atomic_thread_fence.pass.cpp b/test/std/atomics/atomics.fences/atomic_thread_fence.pass.cpp new file mode 100644 index 0000000000000..4f3b0e330e3ef --- /dev/null +++ b/test/std/atomics/atomics.fences/atomic_thread_fence.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// void atomic_thread_fence(memory_order m); + +#include <atomic> + +int main() +{ + std::atomic_thread_fence(std::memory_order_seq_cst); +} diff --git a/test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp b/test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp new file mode 100644 index 0000000000000..8a60f8196dab8 --- /dev/null +++ b/test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// struct atomic_flag + +// void atomic_flag_clear(volatile atomic_flag*); +// void atomic_flag_clear(atomic_flag*); + +#include <atomic> +#include <cassert> + +int main() +{ + { + std::atomic_flag f = ATOMIC_FLAG_INIT; + f.test_and_set(); + atomic_flag_clear(&f); + assert(f.test_and_set() == 0); + } + { + volatile std::atomic_flag f = ATOMIC_FLAG_INIT; + f.test_and_set(); + atomic_flag_clear(&f); + assert(f.test_and_set() == 0); + } +} diff --git a/test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp b/test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp new file mode 100644 index 0000000000000..92e57ecc03f86 --- /dev/null +++ b/test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// struct atomic_flag + +// void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order); +// void atomic_flag_clear_explicit(atomic_flag*, memory_order); + +#include <atomic> +#include <cassert> + +int main() +{ + { + std::atomic_flag f = ATOMIC_FLAG_INIT; + f.test_and_set(); + atomic_flag_clear_explicit(&f, std::memory_order_relaxed); + assert(f.test_and_set() == 0); + } + { + std::atomic_flag f = ATOMIC_FLAG_INIT; + f.test_and_set(); + atomic_flag_clear_explicit(&f, std::memory_order_release); + assert(f.test_and_set() == 0); + } + { + std::atomic_flag f = ATOMIC_FLAG_INIT; + f.test_and_set(); + atomic_flag_clear_explicit(&f, std::memory_order_seq_cst); + assert(f.test_and_set() == 0); + } + { + volatile std::atomic_flag f = ATOMIC_FLAG_INIT; + f.test_and_set(); + atomic_flag_clear_explicit(&f, std::memory_order_relaxed); + assert(f.test_and_set() == 0); + } + { + volatile std::atomic_flag f = ATOMIC_FLAG_INIT; + f.test_and_set(); + atomic_flag_clear_explicit(&f, std::memory_order_release); + assert(f.test_and_set() == 0); + } + { + volatile std::atomic_flag f = ATOMIC_FLAG_INIT; + f.test_and_set(); + atomic_flag_clear_explicit(&f, std::memory_order_seq_cst); + assert(f.test_and_set() == 0); + } +} diff --git a/test/std/atomics/atomics.flag/atomic_flag_test_and_set.pass.cpp b/test/std/atomics/atomics.flag/atomic_flag_test_and_set.pass.cpp new file mode 100644 index 0000000000000..ae82df919549e --- /dev/null +++ b/test/std/atomics/atomics.flag/atomic_flag_test_and_set.pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// struct atomic_flag + +// bool atomic_flag_test_and_set(volatile atomic_flag*); +// bool atomic_flag_test_and_set(atomic_flag*); + +#include <atomic> +#include <cassert> + +int main() +{ + { + std::atomic_flag f; + f.clear(); + assert(atomic_flag_test_and_set(&f) == 0); + assert(f.test_and_set() == 1); + } + { + volatile std::atomic_flag f; + f.clear(); + assert(atomic_flag_test_and_set(&f) == 0); + assert(f.test_and_set() == 1); + } +} diff --git a/test/std/atomics/atomics.flag/atomic_flag_test_and_set_explicit.pass.cpp b/test/std/atomics/atomics.flag/atomic_flag_test_and_set_explicit.pass.cpp new file mode 100644 index 0000000000000..154850697c208 --- /dev/null +++ b/test/std/atomics/atomics.flag/atomic_flag_test_and_set_explicit.pass.cpp @@ -0,0 +1,96 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// struct atomic_flag + +// bool atomic_flag_test_and_set_explicit(volatile atomic_flag*, memory_order); +// bool atomic_flag_test_and_set_explicit(atomic_flag*, memory_order); + +#include <atomic> +#include <cassert> + +int main() +{ + { + std::atomic_flag f; + f.clear(); + assert(atomic_flag_test_and_set_explicit(&f, std::memory_order_relaxed) == 0); + assert(f.test_and_set() == 1); + } + { + std::atomic_flag f; + f.clear(); + assert(atomic_flag_test_and_set_explicit(&f, std::memory_order_consume) == 0); + assert(f.test_and_set() == 1); + } + { + std::atomic_flag f; + f.clear(); + assert(atomic_flag_test_and_set_explicit(&f, std::memory_order_acquire) == 0); + assert(f.test_and_set() == 1); + } + { + std::atomic_flag f; + f.clear(); + assert(atomic_flag_test_and_set_explicit(&f, std::memory_order_release) == 0); + assert(f.test_and_set() == 1); + } + { + std::atomic_flag f; + f.clear(); + assert(atomic_flag_test_and_set_explicit(&f, std::memory_order_acq_rel) == 0); + assert(f.test_and_set() == 1); + } + { + std::atomic_flag f; + f.clear(); + assert(atomic_flag_test_and_set_explicit(&f, std::memory_order_seq_cst) == 0); + assert(f.test_and_set() == 1); + } + { + volatile std::atomic_flag f; + f.clear(); + assert(atomic_flag_test_and_set_explicit(&f, std::memory_order_relaxed) == 0); + assert(f.test_and_set() == 1); + } + { + volatile std::atomic_flag f; + f.clear(); + assert(atomic_flag_test_and_set_explicit(&f, std::memory_order_consume) == 0); + assert(f.test_and_set() == 1); + } + { + volatile std::atomic_flag f; + f.clear(); + assert(atomic_flag_test_and_set_explicit(&f, std::memory_order_acquire) == 0); + assert(f.test_and_set() == 1); + } + { + volatile std::atomic_flag f; + f.clear(); + assert(atomic_flag_test_and_set_explicit(&f, std::memory_order_release) == 0); + assert(f.test_and_set() == 1); + } + { + volatile std::atomic_flag f; + f.clear(); + assert(atomic_flag_test_and_set_explicit(&f, std::memory_order_acq_rel) == 0); + assert(f.test_and_set() == 1); + } + { + volatile std::atomic_flag f; + f.clear(); + assert(atomic_flag_test_and_set_explicit(&f, std::memory_order_seq_cst) == 0); + assert(f.test_and_set() == 1); + } +} diff --git a/test/std/atomics/atomics.flag/clear.pass.cpp b/test/std/atomics/atomics.flag/clear.pass.cpp new file mode 100644 index 0000000000000..7c9362680bba1 --- /dev/null +++ b/test/std/atomics/atomics.flag/clear.pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// struct atomic_flag + +// void clear(memory_order = memory_order_seq_cst); +// void clear(memory_order = memory_order_seq_cst) volatile; + +#include <atomic> +#include <cassert> + +int main() +{ + { + std::atomic_flag f = ATOMIC_FLAG_INIT; + f.test_and_set(); + f.clear(); + assert(f.test_and_set() == 0); + } + { + std::atomic_flag f = ATOMIC_FLAG_INIT; + f.test_and_set(); + f.clear(std::memory_order_relaxed); + assert(f.test_and_set() == 0); + } + { + std::atomic_flag f = ATOMIC_FLAG_INIT; + f.test_and_set(); + f.clear(std::memory_order_release); + assert(f.test_and_set() == 0); + } + { + std::atomic_flag f = ATOMIC_FLAG_INIT; + f.test_and_set(); + f.clear(std::memory_order_seq_cst); + assert(f.test_and_set() == 0); + } + { + volatile std::atomic_flag f = ATOMIC_FLAG_INIT; + f.test_and_set(); + f.clear(); + assert(f.test_and_set() == 0); + } + { + volatile std::atomic_flag f = ATOMIC_FLAG_INIT; + f.test_and_set(); + f.clear(std::memory_order_relaxed); + assert(f.test_and_set() == 0); + } + { + volatile std::atomic_flag f = ATOMIC_FLAG_INIT; + f.test_and_set(); + f.clear(std::memory_order_release); + assert(f.test_and_set() == 0); + } + { + volatile std::atomic_flag f = ATOMIC_FLAG_INIT; + f.test_and_set(); + f.clear(std::memory_order_seq_cst); + assert(f.test_and_set() == 0); + } +} diff --git a/test/std/atomics/atomics.flag/copy_assign.fail.cpp b/test/std/atomics/atomics.flag/copy_assign.fail.cpp new file mode 100644 index 0000000000000..762e3a895441e --- /dev/null +++ b/test/std/atomics/atomics.flag/copy_assign.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <atomic> + +// struct atomic_flag + +// atomic_flag& operator=(const atomic_flag&) = delete; + +#include <atomic> +#include <cassert> + +int main() +{ + std::atomic_flag f0; + std::atomic_flag f; + f = f0; +} diff --git a/test/std/atomics/atomics.flag/copy_ctor.fail.cpp b/test/std/atomics/atomics.flag/copy_ctor.fail.cpp new file mode 100644 index 0000000000000..8d6a86537537f --- /dev/null +++ b/test/std/atomics/atomics.flag/copy_ctor.fail.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <atomic> + +// struct atomic_flag + +// atomic_flag(const atomic_flag&) = delete; + +#include <atomic> +#include <cassert> + +int main() +{ + std::atomic_flag f0; + std::atomic_flag f(f0); +} diff --git a/test/std/atomics/atomics.flag/copy_volatile_assign.fail.cpp b/test/std/atomics/atomics.flag/copy_volatile_assign.fail.cpp new file mode 100644 index 0000000000000..c58c755543917 --- /dev/null +++ b/test/std/atomics/atomics.flag/copy_volatile_assign.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <atomic> + +// struct atomic_flag + +// atomic_flag& operator=(const atomic_flag&) = delete; + +#include <atomic> +#include <cassert> + +int main() +{ + std::atomic_flag f0; + volatile std::atomic_flag f; + f = f0; +} diff --git a/test/std/atomics/atomics.flag/default.pass.cpp b/test/std/atomics/atomics.flag/default.pass.cpp new file mode 100644 index 0000000000000..45f5e709245b8 --- /dev/null +++ b/test/std/atomics/atomics.flag/default.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// struct atomic_flag + +// atomic_flag() = default; + +#include <atomic> +#include <new> +#include <cassert> + +int main() +{ + std::atomic_flag f; + + { + typedef std::atomic_flag A; + _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {1}; + A& zero = *new (storage) A(); + assert(!zero.test_and_set()); + zero.~A(); + } +} diff --git a/test/std/atomics/atomics.flag/init.pass.cpp b/test/std/atomics/atomics.flag/init.pass.cpp new file mode 100644 index 0000000000000..c90509d8fbb5f --- /dev/null +++ b/test/std/atomics/atomics.flag/init.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// struct atomic_flag + +// atomic_flag() = ATOMIC_FLAG_INIT; + +#include <atomic> +#include <cassert> + +int main() +{ + std::atomic_flag f = ATOMIC_FLAG_INIT; + assert(f.test_and_set() == 0); +} diff --git a/test/std/atomics/atomics.flag/test_and_set.pass.cpp b/test/std/atomics/atomics.flag/test_and_set.pass.cpp new file mode 100644 index 0000000000000..210ba2050bb57 --- /dev/null +++ b/test/std/atomics/atomics.flag/test_and_set.pass.cpp @@ -0,0 +1,108 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// struct atomic_flag + +// bool test_and_set(memory_order = memory_order_seq_cst); +// bool test_and_set(memory_order = memory_order_seq_cst) volatile; + +#include <atomic> +#include <cassert> + +int main() +{ + { + std::atomic_flag f; + f.clear(); + assert(f.test_and_set() == 0); + assert(f.test_and_set() == 1); + } + { + std::atomic_flag f; + f.clear(); + assert(f.test_and_set(std::memory_order_relaxed) == 0); + assert(f.test_and_set(std::memory_order_relaxed) == 1); + } + { + std::atomic_flag f; + f.clear(); + assert(f.test_and_set(std::memory_order_consume) == 0); + assert(f.test_and_set(std::memory_order_consume) == 1); + } + { + std::atomic_flag f; + f.clear(); + assert(f.test_and_set(std::memory_order_acquire) == 0); + assert(f.test_and_set(std::memory_order_acquire) == 1); + } + { + std::atomic_flag f; + f.clear(); + assert(f.test_and_set(std::memory_order_release) == 0); + assert(f.test_and_set(std::memory_order_release) == 1); + } + { + std::atomic_flag f; + f.clear(); + assert(f.test_and_set(std::memory_order_acq_rel) == 0); + assert(f.test_and_set(std::memory_order_acq_rel) == 1); + } + { + std::atomic_flag f; + f.clear(); + assert(f.test_and_set(std::memory_order_seq_cst) == 0); + assert(f.test_and_set(std::memory_order_seq_cst) == 1); + } + { + volatile std::atomic_flag f; + f.clear(); + assert(f.test_and_set() == 0); + assert(f.test_and_set() == 1); + } + { + volatile std::atomic_flag f; + f.clear(); + assert(f.test_and_set(std::memory_order_relaxed) == 0); + assert(f.test_and_set(std::memory_order_relaxed) == 1); + } + { + volatile std::atomic_flag f; + f.clear(); + assert(f.test_and_set(std::memory_order_consume) == 0); + assert(f.test_and_set(std::memory_order_consume) == 1); + } + { + volatile std::atomic_flag f; + f.clear(); + assert(f.test_and_set(std::memory_order_acquire) == 0); + assert(f.test_and_set(std::memory_order_acquire) == 1); + } + { + volatile std::atomic_flag f; + f.clear(); + assert(f.test_and_set(std::memory_order_release) == 0); + assert(f.test_and_set(std::memory_order_release) == 1); + } + { + volatile std::atomic_flag f; + f.clear(); + assert(f.test_and_set(std::memory_order_acq_rel) == 0); + assert(f.test_and_set(std::memory_order_acq_rel) == 1); + } + { + volatile std::atomic_flag f; + f.clear(); + assert(f.test_and_set(std::memory_order_seq_cst) == 0); + assert(f.test_and_set(std::memory_order_seq_cst) == 1); + } +} diff --git a/test/std/atomics/atomics.general/nothing_to_do.pass.cpp b/test/std/atomics/atomics.general/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..9a59227abdd98 --- /dev/null +++ b/test/std/atomics/atomics.general/nothing_to_do.pass.cpp @@ -0,0 +1,13 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/atomics/atomics.general/replace_failure_order.pass.cpp b/test/std/atomics/atomics.general/replace_failure_order.pass.cpp new file mode 100644 index 0000000000000..cd0683d6887d5 --- /dev/null +++ b/test/std/atomics/atomics.general/replace_failure_order.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: libcpp-has-no-threads + +// This test verifies behavior specified by [atomics.types.operations.req]/21: +// +// When only one memory_order argument is supplied, the value of success is +// order, and the value of failure is order except that a value of +// memory_order_acq_rel shall be replaced by the value memory_order_acquire +// and a value of memory_order_release shall be replaced by the value +// memory_order_relaxed. +// +// Clang's atomic intrinsics do this for us, but GCC's do not. We don't actually +// have visibility to see what these memory orders are lowered to, but we can at +// least check that they are lowered at all (otherwise there is a compile +// failure with GCC). + +#include <atomic> + +int main() { + std::atomic<int> i; + volatile std::atomic<int> v; + int exp = 0; + + i.compare_exchange_weak(exp, 0, std::memory_order_acq_rel); + i.compare_exchange_weak(exp, 0, std::memory_order_release); + i.compare_exchange_strong(exp, 0, std::memory_order_acq_rel); + i.compare_exchange_strong(exp, 0, std::memory_order_release); + + v.compare_exchange_weak(exp, 0, std::memory_order_acq_rel); + v.compare_exchange_weak(exp, 0, std::memory_order_release); + v.compare_exchange_strong(exp, 0, std::memory_order_acq_rel); + v.compare_exchange_strong(exp, 0, std::memory_order_release); + + return 0; +} diff --git a/test/std/atomics/atomics.lockfree/lockfree.pass.cpp b/test/std/atomics/atomics.lockfree/lockfree.pass.cpp new file mode 100644 index 0000000000000..a975a69a66ff7 --- /dev/null +++ b/test/std/atomics/atomics.lockfree/lockfree.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// #define ATOMIC_CHAR_LOCK_FREE unspecified +// #define ATOMIC_CHAR16_T_LOCK_FREE unspecified +// #define ATOMIC_CHAR32_T_LOCK_FREE unspecified +// #define ATOMIC_WCHAR_T_LOCK_FREE unspecified +// #define ATOMIC_SHORT_LOCK_FREE unspecified +// #define ATOMIC_INT_LOCK_FREE unspecified +// #define ATOMIC_LONG_LOCK_FREE unspecified +// #define ATOMIC_LLONG_LOCK_FREE unspecified + +#include <atomic> +#include <cassert> + +int main() +{ + assert(ATOMIC_CHAR_LOCK_FREE == 0 || + ATOMIC_CHAR_LOCK_FREE == 1 || + ATOMIC_CHAR_LOCK_FREE == 2); + assert(ATOMIC_CHAR16_T_LOCK_FREE == 0 || + ATOMIC_CHAR16_T_LOCK_FREE == 1 || + ATOMIC_CHAR16_T_LOCK_FREE == 2); + assert(ATOMIC_CHAR32_T_LOCK_FREE == 0 || + ATOMIC_CHAR32_T_LOCK_FREE == 1 || + ATOMIC_CHAR32_T_LOCK_FREE == 2); + assert(ATOMIC_WCHAR_T_LOCK_FREE == 0 || + ATOMIC_WCHAR_T_LOCK_FREE == 1 || + ATOMIC_WCHAR_T_LOCK_FREE == 2); + assert(ATOMIC_SHORT_LOCK_FREE == 0 || + ATOMIC_SHORT_LOCK_FREE == 1 || + ATOMIC_SHORT_LOCK_FREE == 2); + assert(ATOMIC_INT_LOCK_FREE == 0 || + ATOMIC_INT_LOCK_FREE == 1 || + ATOMIC_INT_LOCK_FREE == 2); + assert(ATOMIC_LONG_LOCK_FREE == 0 || + ATOMIC_LONG_LOCK_FREE == 1 || + ATOMIC_LONG_LOCK_FREE == 2); + assert(ATOMIC_LLONG_LOCK_FREE == 0 || + ATOMIC_LLONG_LOCK_FREE == 1 || + ATOMIC_LLONG_LOCK_FREE == 2); +} diff --git a/test/std/atomics/atomics.order/kill_dependency.pass.cpp b/test/std/atomics/atomics.order/kill_dependency.pass.cpp new file mode 100644 index 0000000000000..0f0bafcbb0a07 --- /dev/null +++ b/test/std/atomics/atomics.order/kill_dependency.pass.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// template <class T> T kill_dependency(T y); + +#include <atomic> +#include <cassert> + +int main() +{ + assert(std::kill_dependency(5) == 5); + assert(std::kill_dependency(-5.5) == -5.5); +} diff --git a/test/std/atomics/atomics.order/memory_order.pass.cpp b/test/std/atomics/atomics.order/memory_order.pass.cpp new file mode 100644 index 0000000000000..e734a4c7597f5 --- /dev/null +++ b/test/std/atomics/atomics.order/memory_order.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// typedef enum memory_order +// { +// memory_order_relaxed, memory_order_consume, memory_order_acquire, +// memory_order_release, memory_order_acq_rel, memory_order_seq_cst +// } memory_order; + +#include <atomic> +#include <cassert> + +int main() +{ + assert(std::memory_order_relaxed == 0); + assert(std::memory_order_consume == 1); + assert(std::memory_order_acquire == 2); + assert(std::memory_order_release == 3); + assert(std::memory_order_acq_rel == 4); + assert(std::memory_order_seq_cst == 5); + std::memory_order o = std::memory_order_seq_cst; + assert(o == 5); +} diff --git a/test/std/atomics/atomics.syn/nothing_to_do.pass.cpp b/test/std/atomics/atomics.syn/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..9a59227abdd98 --- /dev/null +++ b/test/std/atomics/atomics.syn/nothing_to_do.pass.cpp @@ -0,0 +1,13 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/atomics/atomics.types.generic/address.pass.cpp b/test/std/atomics/atomics.types.generic/address.pass.cpp new file mode 100644 index 0000000000000..3b9f3ce76cad8 --- /dev/null +++ b/test/std/atomics/atomics.types.generic/address.pass.cpp @@ -0,0 +1,140 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// ... test case crashes clang. + +// <atomic> + +// template <class T> +// struct atomic<T*> +// { +// bool is_lock_free() const volatile; +// bool is_lock_free() const; +// void store(T* desr, memory_order m = memory_order_seq_cst) volatile; +// void store(T* desr, memory_order m = memory_order_seq_cst); +// T* load(memory_order m = memory_order_seq_cst) const volatile; +// T* load(memory_order m = memory_order_seq_cst) const; +// operator T*() const volatile; +// operator T*() const; +// T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile; +// T* exchange(T* desr, memory_order m = memory_order_seq_cst); +// bool compare_exchange_weak(T*& expc, T* desr, +// memory_order s, memory_order f) volatile; +// bool compare_exchange_weak(T*& expc, T* desr, +// memory_order s, memory_order f); +// bool compare_exchange_strong(T*& expc, T* desr, +// memory_order s, memory_order f) volatile; +// bool compare_exchange_strong(T*& expc, T* desr, +// memory_order s, memory_order f); +// bool compare_exchange_weak(T*& expc, T* desr, +// memory_order m = memory_order_seq_cst) volatile; +// bool compare_exchange_weak(T*& expc, T* desr, +// memory_order m = memory_order_seq_cst); +// bool compare_exchange_strong(T*& expc, T* desr, +// memory_order m = memory_order_seq_cst) volatile; +// bool compare_exchange_strong(T*& expc, T* desr, +// memory_order m = memory_order_seq_cst); +// T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile; +// T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst); +// T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile; +// T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst); +// +// atomic() = default; +// constexpr atomic(T* desr); +// atomic(const atomic&) = delete; +// atomic& operator=(const atomic&) = delete; +// atomic& operator=(const atomic&) volatile = delete; +// +// T* operator=(T*) volatile; +// T* operator=(T*); +// T* operator++(int) volatile; +// T* operator++(int); +// T* operator--(int) volatile; +// T* operator--(int); +// T* operator++() volatile; +// T* operator++(); +// T* operator--() volatile; +// T* operator--(); +// T* operator+=(ptrdiff_t op) volatile; +// T* operator+=(ptrdiff_t op); +// T* operator-=(ptrdiff_t op) volatile; +// T* operator-=(ptrdiff_t op); +// }; + +#include <atomic> +#include <new> +#include <type_traits> +#include <cassert> + +#include <cmpxchg_loop.h> + +template <class A, class T> +void +do_test() +{ + typedef typename std::remove_pointer<T>::type X; + A obj(T(0)); + assert(obj == T(0)); + std::atomic_init(&obj, T(1)); + assert(obj == T(1)); + std::atomic_init(&obj, T(2)); + assert(obj == T(2)); + bool b0 = obj.is_lock_free(); + obj.store(T(0)); + assert(obj == T(0)); + obj.store(T(1), std::memory_order_release); + assert(obj == T(1)); + assert(obj.load() == T(1)); + assert(obj.load(std::memory_order_acquire) == T(1)); + assert(obj.exchange(T(2)) == T(1)); + assert(obj == T(2)); + assert(obj.exchange(T(3), std::memory_order_relaxed) == T(2)); + assert(obj == T(3)); + T x = obj; + assert(cmpxchg_weak_loop(obj, x, T(2)) == true); + assert(obj == T(2)); + assert(x == T(3)); + assert(obj.compare_exchange_weak(x, T(1)) == false); + assert(obj == T(2)); + assert(x == T(2)); + x = T(2); + assert(obj.compare_exchange_strong(x, T(1)) == true); + assert(obj == T(1)); + assert(x == T(2)); + assert(obj.compare_exchange_strong(x, T(0)) == false); + assert(obj == T(1)); + assert(x == T(1)); + assert((obj = T(0)) == T(0)); + assert(obj == T(0)); + obj = T(2*sizeof(X)); + assert((obj += std::ptrdiff_t(3)) == T(5*sizeof(X))); + assert(obj == T(5*sizeof(X))); + assert((obj -= std::ptrdiff_t(3)) == T(2*sizeof(X))); + assert(obj == T(2*sizeof(X))); + + { + _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {23}; + A& zero = *new (storage) A(); + assert(zero == 0); + zero.~A(); + } +} + +template <class A, class T> +void test() +{ + do_test<A, T>(); + do_test<volatile A, T>(); +} + +int main() +{ + test<std::atomic<int*>, int*>(); +} diff --git a/test/std/atomics/atomics.types.generic/bool.pass.cpp b/test/std/atomics/atomics.types.generic/bool.pass.cpp new file mode 100644 index 0000000000000..dd851e86530c8 --- /dev/null +++ b/test/std/atomics/atomics.types.generic/bool.pass.cpp @@ -0,0 +1,237 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// template <class T> +// struct atomic +// { +// bool is_lock_free() const volatile; +// bool is_lock_free() const; +// void store(T desr, memory_order m = memory_order_seq_cst) volatile; +// void store(T desr, memory_order m = memory_order_seq_cst); +// T load(memory_order m = memory_order_seq_cst) const volatile; +// T load(memory_order m = memory_order_seq_cst) const; +// operator T() const volatile; +// operator T() const; +// T exchange(T desr, memory_order m = memory_order_seq_cst) volatile; +// T exchange(T desr, memory_order m = memory_order_seq_cst); +// bool compare_exchange_weak(T& expc, T desr, +// memory_order s, memory_order f) volatile; +// bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f); +// bool compare_exchange_strong(T& expc, T desr, +// memory_order s, memory_order f) volatile; +// bool compare_exchange_strong(T& expc, T desr, +// memory_order s, memory_order f); +// bool compare_exchange_weak(T& expc, T desr, +// memory_order m = memory_order_seq_cst) volatile; +// bool compare_exchange_weak(T& expc, T desr, +// memory_order m = memory_order_seq_cst); +// bool compare_exchange_strong(T& expc, T desr, +// memory_order m = memory_order_seq_cst) volatile; +// bool compare_exchange_strong(T& expc, T desr, +// memory_order m = memory_order_seq_cst); +// +// atomic() = default; +// constexpr atomic(T desr); +// atomic(const atomic&) = delete; +// atomic& operator=(const atomic&) = delete; +// atomic& operator=(const atomic&) volatile = delete; +// T operator=(T) volatile; +// T operator=(T); +// }; +// +// typedef atomic<bool> atomic_bool; + +#include <atomic> +#include <new> +#include <cassert> + +#include <cmpxchg_loop.h> + +int main() +{ + { + volatile std::atomic<bool> _; + volatile std::atomic<bool> obj(true); + assert(obj == true); + std::atomic_init(&obj, false); + assert(obj == false); + std::atomic_init(&obj, true); + assert(obj == true); + bool b0 = obj.is_lock_free(); + (void)b0; // to placate scan-build + obj.store(false); + assert(obj == false); + obj.store(true, std::memory_order_release); + assert(obj == true); + assert(obj.load() == true); + assert(obj.load(std::memory_order_acquire) == true); + assert(obj.exchange(false) == true); + assert(obj == false); + assert(obj.exchange(true, std::memory_order_relaxed) == false); + assert(obj == true); + bool x = obj; + assert(cmpxchg_weak_loop(obj, x, false) == true); + assert(obj == false); + assert(x == true); + assert(obj.compare_exchange_weak(x, true, + std::memory_order_seq_cst) == false); + assert(obj == false); + assert(x == false); + obj.store(true); + x = true; + assert(cmpxchg_weak_loop(obj, x, false, + std::memory_order_seq_cst, + std::memory_order_seq_cst) == true); + assert(obj == false); + assert(x == true); + x = true; + obj.store(true); + assert(obj.compare_exchange_strong(x, false) == true); + assert(obj == false); + assert(x == true); + assert(obj.compare_exchange_strong(x, true, + std::memory_order_seq_cst) == false); + assert(obj == false); + assert(x == false); + x = true; + obj.store(true); + assert(obj.compare_exchange_strong(x, false, + std::memory_order_seq_cst, + std::memory_order_seq_cst) == true); + assert(obj == false); + assert(x == true); + assert((obj = false) == false); + assert(obj == false); + assert((obj = true) == true); + assert(obj == true); + } + { + std::atomic<bool> _; + std::atomic<bool> obj(true); + assert(obj == true); + std::atomic_init(&obj, false); + assert(obj == false); + std::atomic_init(&obj, true); + assert(obj == true); + bool b0 = obj.is_lock_free(); + (void)b0; // to placate scan-build + obj.store(false); + assert(obj == false); + obj.store(true, std::memory_order_release); + assert(obj == true); + assert(obj.load() == true); + assert(obj.load(std::memory_order_acquire) == true); + assert(obj.exchange(false) == true); + assert(obj == false); + assert(obj.exchange(true, std::memory_order_relaxed) == false); + assert(obj == true); + bool x = obj; + assert(cmpxchg_weak_loop(obj, x, false) == true); + assert(obj == false); + assert(x == true); + assert(obj.compare_exchange_weak(x, true, + std::memory_order_seq_cst) == false); + assert(obj == false); + assert(x == false); + obj.store(true); + x = true; + assert(cmpxchg_weak_loop(obj, x, false, + std::memory_order_seq_cst, + std::memory_order_seq_cst) == true); + assert(obj == false); + assert(x == true); + x = true; + obj.store(true); + assert(obj.compare_exchange_strong(x, false) == true); + assert(obj == false); + assert(x == true); + assert(obj.compare_exchange_strong(x, true, + std::memory_order_seq_cst) == false); + assert(obj == false); + assert(x == false); + x = true; + obj.store(true); + assert(obj.compare_exchange_strong(x, false, + std::memory_order_seq_cst, + std::memory_order_seq_cst) == true); + assert(obj == false); + assert(x == true); + assert((obj = false) == false); + assert(obj == false); + assert((obj = true) == true); + assert(obj == true); + } + { + std::atomic_bool _; + std::atomic_bool obj(true); + assert(obj == true); + std::atomic_init(&obj, false); + assert(obj == false); + std::atomic_init(&obj, true); + assert(obj == true); + bool b0 = obj.is_lock_free(); + (void)b0; // to placate scan-build + obj.store(false); + assert(obj == false); + obj.store(true, std::memory_order_release); + assert(obj == true); + assert(obj.load() == true); + assert(obj.load(std::memory_order_acquire) == true); + assert(obj.exchange(false) == true); + assert(obj == false); + assert(obj.exchange(true, std::memory_order_relaxed) == false); + assert(obj == true); + bool x = obj; + assert(cmpxchg_weak_loop(obj, x, false) == true); + assert(obj == false); + assert(x == true); + assert(obj.compare_exchange_weak(x, true, + std::memory_order_seq_cst) == false); + assert(obj == false); + assert(x == false); + obj.store(true); + x = true; + assert(cmpxchg_weak_loop(obj, x, false, + std::memory_order_seq_cst, + std::memory_order_seq_cst) == true); + assert(obj == false); + assert(x == true); + x = true; + obj.store(true); + assert(obj.compare_exchange_strong(x, false) == true); + assert(obj == false); + assert(x == true); + assert(obj.compare_exchange_strong(x, true, + std::memory_order_seq_cst) == false); + assert(obj == false); + assert(x == false); + x = true; + obj.store(true); + assert(obj.compare_exchange_strong(x, false, + std::memory_order_seq_cst, + std::memory_order_seq_cst) == true); + assert(obj == false); + assert(x == true); + assert((obj = false) == false); + assert(obj == false); + assert((obj = true) == true); + assert(obj == true); + } + { + typedef std::atomic<bool> A; + _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {1}; + A& zero = *new (storage) A(); + assert(zero == false); + zero.~A(); + } +} diff --git a/test/std/atomics/atomics.types.generic/cstdint_typedefs.pass.cpp b/test/std/atomics/atomics.types.generic/cstdint_typedefs.pass.cpp new file mode 100644 index 0000000000000..a7874b9f5af42 --- /dev/null +++ b/test/std/atomics/atomics.types.generic/cstdint_typedefs.pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// typedef atomic<int_least8_t> atomic_int_least8_t; +// typedef atomic<uint_least8_t> atomic_uint_least8_t; +// typedef atomic<int_least16_t> atomic_int_least16_t; +// typedef atomic<uint_least16_t> atomic_uint_least16_t; +// typedef atomic<int_least32_t> atomic_int_least32_t; +// typedef atomic<uint_least32_t> atomic_uint_least32_t; +// typedef atomic<int_least64_t> atomic_int_least64_t; +// typedef atomic<uint_least64_t> atomic_uint_least64_t; +// +// typedef atomic<int_fast8_t> atomic_int_fast8_t; +// typedef atomic<uint_fast8_t> atomic_uint_fast8_t; +// typedef atomic<int_fast16_t> atomic_int_fast16_t; +// typedef atomic<uint_fast16_t> atomic_uint_fast16_t; +// typedef atomic<int_fast32_t> atomic_int_fast32_t; +// typedef atomic<uint_fast32_t> atomic_uint_fast32_t; +// typedef atomic<int_fast64_t> atomic_int_fast64_t; +// typedef atomic<uint_fast64_t> atomic_uint_fast64_t; +// +// typedef atomic<intptr_t> atomic_intptr_t; +// typedef atomic<uintptr_t> atomic_uintptr_t; +// typedef atomic<size_t> atomic_size_t; +// typedef atomic<ptrdiff_t> atomic_ptrdiff_t; +// typedef atomic<intmax_t> atomic_intmax_t; +// typedef atomic<uintmax_t> atomic_uintmax_t; + +#include <atomic> +#include <type_traits> +#include <cstdint> + +int main() +{ + static_assert((std::is_same<std::atomic< std::int_least8_t>, std::atomic_int_least8_t>::value), ""); + static_assert((std::is_same<std::atomic< std::uint_least8_t>, std::atomic_uint_least8_t>::value), ""); + static_assert((std::is_same<std::atomic< std::int_least16_t>, std::atomic_int_least16_t>::value), ""); + static_assert((std::is_same<std::atomic<std::uint_least16_t>, std::atomic_uint_least16_t>::value), ""); + static_assert((std::is_same<std::atomic< std::int_least32_t>, std::atomic_int_least32_t>::value), ""); + static_assert((std::is_same<std::atomic<std::uint_least32_t>, std::atomic_uint_least32_t>::value), ""); + static_assert((std::is_same<std::atomic< std::int_least64_t>, std::atomic_int_least64_t>::value), ""); + static_assert((std::is_same<std::atomic<std::uint_least64_t>, std::atomic_uint_least64_t>::value), ""); + + static_assert((std::is_same<std::atomic< std::int_fast8_t>, std::atomic_int_fast8_t>::value), ""); + static_assert((std::is_same<std::atomic< std::uint_fast8_t>, std::atomic_uint_fast8_t>::value), ""); + static_assert((std::is_same<std::atomic< std::int_fast16_t>, std::atomic_int_fast16_t>::value), ""); + static_assert((std::is_same<std::atomic<std::uint_fast16_t>, std::atomic_uint_fast16_t>::value), ""); + static_assert((std::is_same<std::atomic< std::int_fast32_t>, std::atomic_int_fast32_t>::value), ""); + static_assert((std::is_same<std::atomic<std::uint_fast32_t>, std::atomic_uint_fast32_t>::value), ""); + static_assert((std::is_same<std::atomic< std::int_fast64_t>, std::atomic_int_fast64_t>::value), ""); + static_assert((std::is_same<std::atomic<std::uint_fast64_t>, std::atomic_uint_fast64_t>::value), ""); + + static_assert((std::is_same<std::atomic< std::intptr_t>, std::atomic_intptr_t>::value), ""); + static_assert((std::is_same<std::atomic<std::uintptr_t>, std::atomic_uintptr_t>::value), ""); + static_assert((std::is_same<std::atomic< std::size_t>, std::atomic_size_t>::value), ""); + static_assert((std::is_same<std::atomic<std::ptrdiff_t>, std::atomic_ptrdiff_t>::value), ""); + static_assert((std::is_same<std::atomic< std::intmax_t>, std::atomic_intmax_t>::value), ""); + static_assert((std::is_same<std::atomic<std::uintmax_t>, std::atomic_uintmax_t>::value), ""); +} diff --git a/test/std/atomics/atomics.types.generic/integral.pass.cpp b/test/std/atomics/atomics.types.generic/integral.pass.cpp new file mode 100644 index 0000000000000..f9c758336099c --- /dev/null +++ b/test/std/atomics/atomics.types.generic/integral.pass.cpp @@ -0,0 +1,203 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// template <> +// struct atomic<integral> +// { +// bool is_lock_free() const volatile; +// bool is_lock_free() const; +// void store(integral desr, memory_order m = memory_order_seq_cst) volatile; +// void store(integral desr, memory_order m = memory_order_seq_cst); +// integral load(memory_order m = memory_order_seq_cst) const volatile; +// integral load(memory_order m = memory_order_seq_cst) const; +// operator integral() const volatile; +// operator integral() const; +// integral exchange(integral desr, +// memory_order m = memory_order_seq_cst) volatile; +// integral exchange(integral desr, memory_order m = memory_order_seq_cst); +// bool compare_exchange_weak(integral& expc, integral desr, +// memory_order s, memory_order f) volatile; +// bool compare_exchange_weak(integral& expc, integral desr, +// memory_order s, memory_order f); +// bool compare_exchange_strong(integral& expc, integral desr, +// memory_order s, memory_order f) volatile; +// bool compare_exchange_strong(integral& expc, integral desr, +// memory_order s, memory_order f); +// bool compare_exchange_weak(integral& expc, integral desr, +// memory_order m = memory_order_seq_cst) volatile; +// bool compare_exchange_weak(integral& expc, integral desr, +// memory_order m = memory_order_seq_cst); +// bool compare_exchange_strong(integral& expc, integral desr, +// memory_order m = memory_order_seq_cst) volatile; +// bool compare_exchange_strong(integral& expc, integral desr, +// memory_order m = memory_order_seq_cst); +// +// integral +// fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile; +// integral fetch_add(integral op, memory_order m = memory_order_seq_cst); +// integral +// fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile; +// integral fetch_sub(integral op, memory_order m = memory_order_seq_cst); +// integral +// fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile; +// integral fetch_and(integral op, memory_order m = memory_order_seq_cst); +// integral +// fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile; +// integral fetch_or(integral op, memory_order m = memory_order_seq_cst); +// integral +// fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile; +// integral fetch_xor(integral op, memory_order m = memory_order_seq_cst); +// +// atomic() = default; +// constexpr atomic(integral desr); +// atomic(const atomic&) = delete; +// atomic& operator=(const atomic&) = delete; +// atomic& operator=(const atomic&) volatile = delete; +// integral operator=(integral desr) volatile; +// integral operator=(integral desr); +// +// integral operator++(int) volatile; +// integral operator++(int); +// integral operator--(int) volatile; +// integral operator--(int); +// integral operator++() volatile; +// integral operator++(); +// integral operator--() volatile; +// integral operator--(); +// integral operator+=(integral op) volatile; +// integral operator+=(integral op); +// integral operator-=(integral op) volatile; +// integral operator-=(integral op); +// integral operator&=(integral op) volatile; +// integral operator&=(integral op); +// integral operator|=(integral op) volatile; +// integral operator|=(integral op); +// integral operator^=(integral op) volatile; +// integral operator^=(integral op); +// }; + +#include <atomic> +#include <new> +#include <cassert> + +#include <cmpxchg_loop.h> + +template <class A, class T> +void +do_test() +{ + A obj(T(0)); + assert(obj == T(0)); + std::atomic_init(&obj, T(1)); + assert(obj == T(1)); + std::atomic_init(&obj, T(2)); + assert(obj == T(2)); + bool b0 = obj.is_lock_free(); + obj.store(T(0)); + assert(obj == T(0)); + obj.store(T(1), std::memory_order_release); + assert(obj == T(1)); + assert(obj.load() == T(1)); + assert(obj.load(std::memory_order_acquire) == T(1)); + assert(obj.exchange(T(2)) == T(1)); + assert(obj == T(2)); + assert(obj.exchange(T(3), std::memory_order_relaxed) == T(2)); + assert(obj == T(3)); + T x = obj; + assert(cmpxchg_weak_loop(obj, x, T(2)) == true); + assert(obj == T(2)); + assert(x == T(3)); + assert(obj.compare_exchange_weak(x, T(1)) == false); + assert(obj == T(2)); + assert(x == T(2)); + x = T(2); + assert(obj.compare_exchange_strong(x, T(1)) == true); + assert(obj == T(1)); + assert(x == T(2)); + assert(obj.compare_exchange_strong(x, T(0)) == false); + assert(obj == T(1)); + assert(x == T(1)); + assert((obj = T(0)) == T(0)); + assert(obj == T(0)); + assert(obj++ == T(0)); + assert(obj == T(1)); + assert(++obj == T(2)); + assert(obj == T(2)); + assert(--obj == T(1)); + assert(obj == T(1)); + assert(obj-- == T(1)); + assert(obj == T(0)); + obj = T(2); + assert((obj += T(3)) == T(5)); + assert(obj == T(5)); + assert((obj -= T(3)) == T(2)); + assert(obj == T(2)); + assert((obj |= T(5)) == T(7)); + assert(obj == T(7)); + assert((obj &= T(0xF)) == T(7)); + assert(obj == T(7)); + assert((obj ^= T(0xF)) == T(8)); + assert(obj == T(8)); + + { + _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {23}; + A& zero = *new (storage) A(); + assert(zero == 0); + zero.~A(); + } +} + +template <class A, class T> +void test() +{ + do_test<A, T>(); + do_test<volatile A, T>(); +} + + +int main() +{ + test<std::atomic_char, char>(); + test<std::atomic_schar, signed char>(); + test<std::atomic_uchar, unsigned char>(); + test<std::atomic_short, short>(); + test<std::atomic_ushort, unsigned short>(); + test<std::atomic_int, int>(); + test<std::atomic_uint, unsigned int>(); + test<std::atomic_long, long>(); + test<std::atomic_ulong, unsigned long>(); + test<std::atomic_llong, long long>(); + test<std::atomic_ullong, unsigned long long>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<std::atomic_char16_t, char16_t>(); + test<std::atomic_char32_t, char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + test<std::atomic_wchar_t, wchar_t>(); + + test<volatile std::atomic_char, char>(); + test<volatile std::atomic_schar, signed char>(); + test<volatile std::atomic_uchar, unsigned char>(); + test<volatile std::atomic_short, short>(); + test<volatile std::atomic_ushort, unsigned short>(); + test<volatile std::atomic_int, int>(); + test<volatile std::atomic_uint, unsigned int>(); + test<volatile std::atomic_long, long>(); + test<volatile std::atomic_ulong, unsigned long>(); + test<volatile std::atomic_llong, long long>(); + test<volatile std::atomic_ullong, unsigned long long>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<volatile std::atomic_char16_t, char16_t>(); + test<volatile std::atomic_char32_t, char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + test<volatile std::atomic_wchar_t, wchar_t>(); +} diff --git a/test/std/atomics/atomics.types.generic/integral_typedefs.pass.cpp b/test/std/atomics/atomics.types.generic/integral_typedefs.pass.cpp new file mode 100644 index 0000000000000..e8fae85fb4b3b --- /dev/null +++ b/test/std/atomics/atomics.types.generic/integral_typedefs.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// typedef atomic<char> atomic_char; +// typedef atomic<signed char> atomic_schar; +// typedef atomic<unsigned char> atomic_uchar; +// typedef atomic<short> atomic_short; +// typedef atomic<unsigned short> atomic_ushort; +// typedef atomic<int> atomic_int; +// typedef atomic<unsigned int> atomic_uint; +// typedef atomic<long> atomic_long; +// typedef atomic<unsigned long> atomic_ulong; +// typedef atomic<long long> atomic_llong; +// typedef atomic<unsigned long long> atomic_ullong; +// typedef atomic<char16_t> atomic_char16_t; +// typedef atomic<char32_t> atomic_char32_t; +// typedef atomic<wchar_t> atomic_wchar_t; + +#include <atomic> +#include <type_traits> + +int main() +{ + static_assert((std::is_same<std::atomic<char>, std::atomic_char>::value), ""); + static_assert((std::is_same<std::atomic<signed char>, std::atomic_schar>::value), ""); + static_assert((std::is_same<std::atomic<unsigned char>, std::atomic_uchar>::value), ""); + static_assert((std::is_same<std::atomic<short>, std::atomic_short>::value), ""); + static_assert((std::is_same<std::atomic<unsigned short>, std::atomic_ushort>::value), ""); + static_assert((std::is_same<std::atomic<int>, std::atomic_int>::value), ""); + static_assert((std::is_same<std::atomic<unsigned int>, std::atomic_uint>::value), ""); + static_assert((std::is_same<std::atomic<long>, std::atomic_long>::value), ""); + static_assert((std::is_same<std::atomic<unsigned long>, std::atomic_ulong>::value), ""); + static_assert((std::is_same<std::atomic<long long>, std::atomic_llong>::value), ""); + static_assert((std::is_same<std::atomic<unsigned long long>, std::atomic_ullong>::value), ""); + static_assert((std::is_same<std::atomic<wchar_t>, std::atomic_wchar_t>::value), ""); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + static_assert((std::is_same<std::atomic<char16_t>, std::atomic_char16_t>::value), ""); + static_assert((std::is_same<std::atomic<char32_t>, std::atomic_char32_t>::value), ""); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS +} diff --git a/test/std/atomics/atomics.types.generic/trivially_copyable.fail.cpp b/test/std/atomics/atomics.types.generic/trivially_copyable.fail.cpp new file mode 100644 index 0000000000000..f2bf4db0de485 --- /dev/null +++ b/test/std/atomics/atomics.types.generic/trivially_copyable.fail.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <atomic> + +// template <class T> +// struct atomic +// { +// bool is_lock_free() const volatile noexcept; +// bool is_lock_free() const noexcept; +// void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; +// void store(T desr, memory_order m = memory_order_seq_cst) noexcept; +// T load(memory_order m = memory_order_seq_cst) const volatile noexcept; +// T load(memory_order m = memory_order_seq_cst) const noexcept; +// operator T() const volatile noexcept; +// operator T() const noexcept; +// T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; +// T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept; +// bool compare_exchange_weak(T& expc, T desr, +// memory_order s, memory_order f) volatile noexcept; +// bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept; +// bool compare_exchange_strong(T& expc, T desr, +// memory_order s, memory_order f) volatile noexcept; +// bool compare_exchange_strong(T& expc, T desr, +// memory_order s, memory_order f) noexcept; +// bool compare_exchange_weak(T& expc, T desr, +// memory_order m = memory_order_seq_cst) volatile noexcept; +// bool compare_exchange_weak(T& expc, T desr, +// memory_order m = memory_order_seq_cst) noexcept; +// bool compare_exchange_strong(T& expc, T desr, +// memory_order m = memory_order_seq_cst) volatile noexcept; +// bool compare_exchange_strong(T& expc, T desr, +// memory_order m = memory_order_seq_cst) noexcept; +// +// atomic() noexcept = default; +// constexpr atomic(T desr) noexcept; +// atomic(const atomic&) = delete; +// atomic& operator=(const atomic&) = delete; +// atomic& operator=(const atomic&) volatile = delete; +// T operator=(T) volatile noexcept; +// T operator=(T) noexcept; +// }; + +#include <atomic> +#include <new> +#include <cassert> +#include <thread> // for thread_id +#include <chrono> // for nanoseconds + +struct NotTriviallyCopyable { + NotTriviallyCopyable ( int i ) : i_(i) {} + NotTriviallyCopyable ( const NotTriviallyCopyable &rhs) : i_(rhs.i_) {} + int i_; + }; + +template <class T> +void test ( T t ) { + std::atomic<T> t0(t); + } + +int main() +{ + test(NotTriviallyCopyable(42)); +} diff --git a/test/std/atomics/atomics.types.generic/trivially_copyable.pass.cpp b/test/std/atomics/atomics.types.generic/trivially_copyable.pass.cpp new file mode 100644 index 0000000000000..5b094f0a89c1d --- /dev/null +++ b/test/std/atomics/atomics.types.generic/trivially_copyable.pass.cpp @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// NOTE: atomic<> of a TriviallyCopyable class is wrongly rejected by older +// clang versions. It was fixed right before the llvm 3.5 release. See PR18097. +// XFAIL: apple-clang-6.0, clang-3.4, clang-3.3 + +// <atomic> + +// template <class T> +// struct atomic +// { +// bool is_lock_free() const volatile noexcept; +// bool is_lock_free() const noexcept; +// void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; +// void store(T desr, memory_order m = memory_order_seq_cst) noexcept; +// T load(memory_order m = memory_order_seq_cst) const volatile noexcept; +// T load(memory_order m = memory_order_seq_cst) const noexcept; +// operator T() const volatile noexcept; +// operator T() const noexcept; +// T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; +// T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept; +// bool compare_exchange_weak(T& expc, T desr, +// memory_order s, memory_order f) volatile noexcept; +// bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept; +// bool compare_exchange_strong(T& expc, T desr, +// memory_order s, memory_order f) volatile noexcept; +// bool compare_exchange_strong(T& expc, T desr, +// memory_order s, memory_order f) noexcept; +// bool compare_exchange_weak(T& expc, T desr, +// memory_order m = memory_order_seq_cst) volatile noexcept; +// bool compare_exchange_weak(T& expc, T desr, +// memory_order m = memory_order_seq_cst) noexcept; +// bool compare_exchange_strong(T& expc, T desr, +// memory_order m = memory_order_seq_cst) volatile noexcept; +// bool compare_exchange_strong(T& expc, T desr, +// memory_order m = memory_order_seq_cst) noexcept; +// +// atomic() noexcept = default; +// constexpr atomic(T desr) noexcept; +// atomic(const atomic&) = delete; +// atomic& operator=(const atomic&) = delete; +// atomic& operator=(const atomic&) volatile = delete; +// T operator=(T) volatile noexcept; +// T operator=(T) noexcept; +// }; + +#include <atomic> +#include <new> +#include <cassert> +#include <thread> // for thread_id +#include <chrono> // for nanoseconds + +struct TriviallyCopyable { + TriviallyCopyable ( int i ) : i_(i) {} + int i_; + }; + +template <class T> +void test ( T t ) { + std::atomic<T> t0(t); + } + +int main() +{ + test(TriviallyCopyable(42)); + test(std::this_thread::get_id()); + test(std::chrono::nanoseconds(2)); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.arith/nothing_to_do.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.arith/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..9a59227abdd98 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.arith/nothing_to_do.pass.cpp @@ -0,0 +1,13 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.general/nothing_to_do.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.general/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..9a59227abdd98 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.general/nothing_to_do.pass.cpp @@ -0,0 +1,13 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.pointer/nothing_to_do.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.pointer/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..9a59227abdd98 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.pointer/nothing_to_do.pass.cpp @@ -0,0 +1,13 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp new file mode 100644 index 0000000000000..f1cc993ed33e0 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// ... assertion fails line 34 + +// <atomic> + +// template <class T> +// bool +// atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr); +// +// template <class T> +// bool +// atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + { + typedef std::atomic<T> A; + A a; + T t(T(1)); + std::atomic_init(&a, t); + assert(std::atomic_compare_exchange_strong(&a, &t, T(2)) == true); + assert(a == T(2)); + assert(t == T(1)); + assert(std::atomic_compare_exchange_strong(&a, &t, T(3)) == false); + assert(a == T(2)); + assert(t == T(2)); + } + { + typedef std::atomic<T> A; + volatile A a; + T t(T(1)); + std::atomic_init(&a, t); + assert(std::atomic_compare_exchange_strong(&a, &t, T(2)) == true); + assert(a == T(2)); + assert(t == T(1)); + assert(std::atomic_compare_exchange_strong(&a, &t, T(3)) == false); + assert(a == T(2)); + assert(t == T(2)); + } +} + +struct A +{ + int i; + + explicit A(int d = 0) noexcept {i=d;} + + friend bool operator==(const A& x, const A& y) + {return x.i == y.i;} +}; + +int main() +{ + test<A>(); + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + test<int*>(); + test<const int*>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp new file mode 100644 index 0000000000000..f667ab7f139b1 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp @@ -0,0 +1,95 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// ... assertion fails line 38 + +// <atomic> + +// template <class T> +// bool +// atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj, T* expc, +// T desr, +// memory_order s, memory_order f); +// +// template <class T> +// bool +// atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc, T desr, +// memory_order s, memory_order f); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + { + typedef std::atomic<T> A; + A a; + T t(T(1)); + std::atomic_init(&a, t); + assert(std::atomic_compare_exchange_strong_explicit(&a, &t, T(2), + std::memory_order_seq_cst, std::memory_order_seq_cst) == true); + assert(a == T(2)); + assert(t == T(1)); + assert(std::atomic_compare_exchange_strong_explicit(&a, &t, T(3), + std::memory_order_seq_cst, std::memory_order_seq_cst) == false); + assert(a == T(2)); + assert(t == T(2)); + } + { + typedef std::atomic<T> A; + volatile A a; + T t(T(1)); + std::atomic_init(&a, t); + assert(std::atomic_compare_exchange_strong_explicit(&a, &t, T(2), + std::memory_order_seq_cst, std::memory_order_seq_cst) == true); + assert(a == T(2)); + assert(t == T(1)); + assert(std::atomic_compare_exchange_strong_explicit(&a, &t, T(3), + std::memory_order_seq_cst, std::memory_order_seq_cst) == false); + assert(a == T(2)); + assert(t == T(2)); + } +} + +struct A +{ + int i; + + explicit A(int d = 0) noexcept {i=d;} + + friend bool operator==(const A& x, const A& y) + {return x.i == y.i;} +}; + +int main() +{ + test<A>(); + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + test<int*>(); + test<const int*>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp new file mode 100644 index 0000000000000..175c445d45608 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// ... assertion fails line 34 + +// <atomic> + +// template <class T> +// bool +// atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr); +// +// template <class T> +// bool +// atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr); + +#include <atomic> +#include <type_traits> +#include <cassert> + +#include <cmpxchg_loop.h> + +template <class T> +void +test() +{ + { + typedef std::atomic<T> A; + A a; + T t(T(1)); + std::atomic_init(&a, t); + assert(c_cmpxchg_weak_loop(&a, &t, T(2)) == true); + assert(a == T(2)); + assert(t == T(1)); + assert(std::atomic_compare_exchange_weak(&a, &t, T(3)) == false); + assert(a == T(2)); + assert(t == T(2)); + } + { + typedef std::atomic<T> A; + volatile A a; + T t(T(1)); + std::atomic_init(&a, t); + assert(c_cmpxchg_weak_loop(&a, &t, T(2)) == true); + assert(a == T(2)); + assert(t == T(1)); + assert(std::atomic_compare_exchange_weak(&a, &t, T(3)) == false); + assert(a == T(2)); + assert(t == T(2)); + } +} + +struct A +{ + int i; + + explicit A(int d = 0) noexcept {i=d;} + + friend bool operator==(const A& x, const A& y) + {return x.i == y.i;} +}; + +int main() +{ + test<A>(); + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + test<int*>(); + test<const int*>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp new file mode 100644 index 0000000000000..46f80bfbcb7bf --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// ... assertion fails line 38 + +// <atomic> + +// template <class T> +// bool +// atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc, +// T desr, +// memory_order s, memory_order f); +// +// template <class T> +// bool +// atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr, +// memory_order s, memory_order f); + +#include <atomic> +#include <type_traits> +#include <cassert> + +#include <cmpxchg_loop.h> + +template <class T> +void +test() +{ + { + typedef std::atomic<T> A; + A a; + T t(T(1)); + std::atomic_init(&a, t); + assert(c_cmpxchg_weak_loop(&a, &t, T(2), + std::memory_order_seq_cst, std::memory_order_seq_cst) == true); + assert(a == T(2)); + assert(t == T(1)); + assert(std::atomic_compare_exchange_weak_explicit(&a, &t, T(3), + std::memory_order_seq_cst, std::memory_order_seq_cst) == false); + assert(a == T(2)); + assert(t == T(2)); + } + { + typedef std::atomic<T> A; + volatile A a; + T t(T(1)); + std::atomic_init(&a, t); + assert(c_cmpxchg_weak_loop(&a, &t, T(2), + std::memory_order_seq_cst, std::memory_order_seq_cst) == true); + assert(a == T(2)); + assert(t == T(1)); + assert(std::atomic_compare_exchange_weak_explicit(&a, &t, T(3), + std::memory_order_seq_cst, std::memory_order_seq_cst) == false); + assert(a == T(2)); + assert(t == T(2)); + } +} + +struct A +{ + int i; + + explicit A(int d = 0) noexcept {i=d;} + + friend bool operator==(const A& x, const A& y) + {return x.i == y.i;} +}; + +int main() +{ + test<A>(); + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + test<int*>(); + test<const int*>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp new file mode 100644 index 0000000000000..525e74aa63743 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// ... fails assertion line 31 + +// <atomic> + +// template <class T> +// T +// atomic_exchange(volatile atomic<T>* obj, T desr); +// +// template <class T> +// T +// atomic_exchange(atomic<T>* obj, T desr); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + typedef std::atomic<T> A; + A t; + std::atomic_init(&t, T(1)); + assert(std::atomic_exchange(&t, T(2)) == T(1)); + assert(t == T(2)); + volatile A vt; + std::atomic_init(&vt, T(3)); + assert(std::atomic_exchange(&vt, T(4)) == T(3)); + assert(vt == T(4)); +} + +struct A +{ + int i; + + explicit A(int d = 0) noexcept {i=d;} + + friend bool operator==(const A& x, const A& y) + {return x.i == y.i;} +}; + +int main() +{ + test<A>(); + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + test<int*>(); + test<const int*>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp new file mode 100644 index 0000000000000..9fe4ac816448e --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// ... assertion fails line 32 + +// <atomic> + +// template <class T> +// T +// atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m); +// +// template <class T> +// T +// atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + typedef std::atomic<T> A; + A t; + std::atomic_init(&t, T(1)); + assert(std::atomic_exchange_explicit(&t, T(2), std::memory_order_seq_cst) + == T(1)); + assert(t == T(2)); + volatile A vt; + std::atomic_init(&vt, T(3)); + assert(std::atomic_exchange_explicit(&vt, T(4), std::memory_order_seq_cst) + == T(3)); + assert(vt == T(4)); +} + +struct A +{ + int i; + + explicit A(int d = 0) noexcept {i=d;} + + friend bool operator==(const A& x, const A& y) + {return x.i == y.i;} +}; + +int main() +{ + test<A>(); + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + test<int*>(); + test<const int*>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp new file mode 100644 index 0000000000000..3408def9058a2 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp @@ -0,0 +1,111 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// ... test crashes clang + +// <atomic> + +// template <class Integral> +// Integral +// atomic_fetch_add(volatile atomic<Integral>* obj, Integral op); +// +// template <class Integral> +// Integral +// atomic_fetch_add(atomic<Integral>* obj, Integral op); +// +// template <class T> +// T* +// atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op); +// +// template <class T> +// T* +// atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + { + typedef std::atomic<T> A; + A t; + std::atomic_init(&t, T(1)); + assert(std::atomic_fetch_add(&t, T(2)) == T(1)); + assert(t == T(3)); + } + { + typedef std::atomic<T> A; + volatile A t; + std::atomic_init(&t, T(1)); + assert(std::atomic_fetch_add(&t, T(2)) == T(1)); + assert(t == T(3)); + } +} + +template <class T> +void +testp() +{ + { + typedef std::atomic<T> A; + typedef typename std::remove_pointer<T>::type X; + A t; + std::atomic_init(&t, T(1*sizeof(X))); + assert(std::atomic_fetch_add(&t, 2) == T(1*sizeof(X))); + assert(t == T(3*sizeof(X))); + } + { + typedef std::atomic<T> A; + typedef typename std::remove_pointer<T>::type X; + volatile A t; + std::atomic_init(&t, T(1*sizeof(X))); + assert(std::atomic_fetch_add(&t, 2) == T(1*sizeof(X))); + assert(t == T(3*sizeof(X))); + } +} + +struct A +{ + int i; + + explicit A(int d = 0) noexcept {i=d;} + A(const A& a) : i(a.i) {} + A(const volatile A& a) : i(a.i) {} + + void operator=(const volatile A& a) volatile {i = a.i;} + + friend bool operator==(const A& x, const A& y) + {return x.i == y.i;} +}; + +int main() +{ + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + testp<int*>(); + testp<const int*>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp new file mode 100644 index 0000000000000..9977bd491e7a1 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// ... test crashes clang + +// <atomic> + +// template <class Integral> +// Integral +// atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op, +// memory_order m); +// template <class Integral> +// Integral +// atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op, +// memory_order m); +// template <class T> +// T* +// atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op, +// memory_order m); +// template <class T> +// T* +// atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + { + typedef std::atomic<T> A; + A t; + std::atomic_init(&t, T(1)); + assert(std::atomic_fetch_add_explicit(&t, T(2), + std::memory_order_seq_cst) == T(1)); + assert(t == T(3)); + } + { + typedef std::atomic<T> A; + volatile A t; + std::atomic_init(&t, T(1)); + assert(std::atomic_fetch_add_explicit(&t, T(2), + std::memory_order_seq_cst) == T(1)); + assert(t == T(3)); + } +} + +template <class T> +void +testp() +{ + { + typedef std::atomic<T> A; + typedef typename std::remove_pointer<T>::type X; + A t; + std::atomic_init(&t, T(1*sizeof(X))); + assert(std::atomic_fetch_add_explicit(&t, 2, + std::memory_order_seq_cst) == T(1*sizeof(X))); + assert(t == T(3*sizeof(X))); + } + { + typedef std::atomic<T> A; + typedef typename std::remove_pointer<T>::type X; + volatile A t; + std::atomic_init(&t, T(1*sizeof(X))); + assert(std::atomic_fetch_add_explicit(&t, 2, + std::memory_order_seq_cst) == T(1*sizeof(X))); + assert(t == T(3*sizeof(X))); + } +} + +struct A +{ + int i; + + explicit A(int d = 0) noexcept {i=d;} + A(const A& a) : i(a.i) {} + A(const volatile A& a) : i(a.i) {} + + void operator=(const volatile A& a) volatile {i = a.i;} + + friend bool operator==(const A& x, const A& y) + {return x.i == y.i;} +}; + +int main() +{ + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + testp<int*>(); + testp<const int*>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp new file mode 100644 index 0000000000000..4c7c0432efc9f --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// template <class Integral> +// Integral +// atomic_fetch_and(volatile atomic<Integral>* obj, Integral op); +// +// template <class Integral> +// Integral +// atomic_fetch_and(atomic<Integral>* obj, Integral op); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + { + typedef std::atomic<T> A; + A t; + std::atomic_init(&t, T(1)); + assert(std::atomic_fetch_and(&t, T(2)) == T(1)); + assert(t == T(0)); + } + { + typedef std::atomic<T> A; + volatile A t; + std::atomic_init(&t, T(3)); + assert(std::atomic_fetch_and(&t, T(2)) == T(3)); + assert(t == T(2)); + } +} + +int main() +{ + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp new file mode 100644 index 0000000000000..d83bbf264de52 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// template <class Integral> +// Integral +// atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op); +// +// template <class Integral> +// Integral +// atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + { + typedef std::atomic<T> A; + A t; + std::atomic_init(&t, T(1)); + assert(std::atomic_fetch_and_explicit(&t, T(2), + std::memory_order_seq_cst) == T(1)); + assert(t == T(0)); + } + { + typedef std::atomic<T> A; + volatile A t; + std::atomic_init(&t, T(3)); + assert(std::atomic_fetch_and_explicit(&t, T(2), + std::memory_order_seq_cst) == T(3)); + assert(t == T(2)); + } +} + +int main() +{ + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp new file mode 100644 index 0000000000000..acf6d439de435 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// template <class Integral> +// Integral +// atomic_fetch_or(volatile atomic<Integral>* obj, Integral op); +// +// template <class Integral> +// Integral +// atomic_fetch_or(atomic<Integral>* obj, Integral op); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + { + typedef std::atomic<T> A; + A t; + std::atomic_init(&t, T(1)); + assert(std::atomic_fetch_or(&t, T(2)) == T(1)); + assert(t == T(3)); + } + { + typedef std::atomic<T> A; + volatile A t; + std::atomic_init(&t, T(3)); + assert(std::atomic_fetch_or(&t, T(2)) == T(3)); + assert(t == T(3)); + } +} + +int main() +{ + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp new file mode 100644 index 0000000000000..72685e4d9408c --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// template <class Integral> +// Integral +// atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op); +// +// template <class Integral> +// Integral +// atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + { + typedef std::atomic<T> A; + A t; + std::atomic_init(&t, T(1)); + assert(std::atomic_fetch_or_explicit(&t, T(2), + std::memory_order_seq_cst) == T(1)); + assert(t == T(3)); + } + { + typedef std::atomic<T> A; + volatile A t; + std::atomic_init(&t, T(3)); + assert(std::atomic_fetch_or_explicit(&t, T(2), + std::memory_order_seq_cst) == T(3)); + assert(t == T(3)); + } +} + +int main() +{ + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp new file mode 100644 index 0000000000000..ed8b541291af9 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp @@ -0,0 +1,111 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// ... test crashes clang + +// <atomic> + +// template <class Integral> +// Integral +// atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op); +// +// template <class Integral> +// Integral +// atomic_fetch_sub(atomic<Integral>* obj, Integral op); +// +// template <class T> +// T* +// atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op); +// +// template <class T> +// T* +// atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + { + typedef std::atomic<T> A; + A t; + std::atomic_init(&t, T(3)); + assert(std::atomic_fetch_sub(&t, T(2)) == T(3)); + assert(t == T(1)); + } + { + typedef std::atomic<T> A; + volatile A t; + std::atomic_init(&t, T(3)); + assert(std::atomic_fetch_sub(&t, T(2)) == T(3)); + assert(t == T(1)); + } +} + +template <class T> +void +testp() +{ + { + typedef std::atomic<T> A; + typedef typename std::remove_pointer<T>::type X; + A t; + std::atomic_init(&t, T(3*sizeof(X))); + assert(std::atomic_fetch_sub(&t, 2) == T(3*sizeof(X))); + assert(t == T(1*sizeof(X))); + } + { + typedef std::atomic<T> A; + typedef typename std::remove_pointer<T>::type X; + volatile A t; + std::atomic_init(&t, T(3*sizeof(X))); + assert(std::atomic_fetch_sub(&t, 2) == T(3*sizeof(X))); + assert(t == T(1*sizeof(X))); + } +} + +struct A +{ + int i; + + explicit A(int d = 0) noexcept {i=d;} + A(const A& a) : i(a.i) {} + A(const volatile A& a) : i(a.i) {} + + void operator=(const volatile A& a) volatile {i = a.i;} + + friend bool operator==(const A& x, const A& y) + {return x.i == y.i;} +}; + +int main() +{ + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + testp<int*>(); + testp<const int*>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp new file mode 100644 index 0000000000000..e6c92eada6df9 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// ... test crashes clang + +// <atomic> + +// template <class Integral> +// Integral +// atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op, +// memory_order m); +// template <class Integral> +// Integral +// atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op, +// memory_order m); +// +// template <class T> +// T* +// atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op, +// memory_order m); +// template <class T> +// T* +// atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + { + typedef std::atomic<T> A; + A t; + std::atomic_init(&t, T(3)); + assert(std::atomic_fetch_sub_explicit(&t, T(2), + std::memory_order_seq_cst) == T(3)); + assert(t == T(1)); + } + { + typedef std::atomic<T> A; + volatile A t; + std::atomic_init(&t, T(3)); + assert(std::atomic_fetch_sub_explicit(&t, T(2), + std::memory_order_seq_cst) == T(3)); + assert(t == T(1)); + } +} + +template <class T> +void +testp() +{ + { + typedef std::atomic<T> A; + typedef typename std::remove_pointer<T>::type X; + A t; + std::atomic_init(&t, T(3*sizeof(X))); + assert(std::atomic_fetch_sub_explicit(&t, 2, + std::memory_order_seq_cst) == T(3*sizeof(X))); + assert(t == T(1*sizeof(X))); + } + { + typedef std::atomic<T> A; + typedef typename std::remove_pointer<T>::type X; + volatile A t; + std::atomic_init(&t, T(3*sizeof(X))); + assert(std::atomic_fetch_sub_explicit(&t, 2, + std::memory_order_seq_cst) == T(3*sizeof(X))); + assert(t == T(1*sizeof(X))); + } +} + +struct A +{ + int i; + + explicit A(int d = 0) noexcept {i=d;} + A(const A& a) : i(a.i) {} + A(const volatile A& a) : i(a.i) {} + + void operator=(const volatile A& a) volatile {i = a.i;} + + friend bool operator==(const A& x, const A& y) + {return x.i == y.i;} +}; + +int main() +{ + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + testp<int*>(); + testp<const int*>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp new file mode 100644 index 0000000000000..fc6b97b7db453 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// template <class Integral> +// Integral +// atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op); +// +// template <class Integral> +// Integral +// atomic_fetch_xor(atomic<Integral>* obj, Integral op); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + { + typedef std::atomic<T> A; + A t; + std::atomic_init(&t, T(1)); + assert(std::atomic_fetch_xor(&t, T(2)) == T(1)); + assert(t == T(3)); + } + { + typedef std::atomic<T> A; + volatile A t; + std::atomic_init(&t, T(3)); + assert(std::atomic_fetch_xor(&t, T(2)) == T(3)); + assert(t == T(1)); + } +} + +int main() +{ + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp new file mode 100644 index 0000000000000..58772aa4d1522 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// template <class Integral> +// Integral +// atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op); +// +// template <class Integral> +// Integral +// atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + { + typedef std::atomic<T> A; + A t; + std::atomic_init(&t, T(1)); + assert(std::atomic_fetch_xor_explicit(&t, T(2), + std::memory_order_seq_cst) == T(1)); + assert(t == T(3)); + } + { + typedef std::atomic<T> A; + volatile A t; + std::atomic_init(&t, T(3)); + assert(std::atomic_fetch_xor_explicit(&t, T(2), + std::memory_order_seq_cst) == T(3)); + assert(t == T(1)); + } +} + +int main() +{ + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp new file mode 100644 index 0000000000000..137b6f60f7460 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// ... assertion fails line 34 + +// <atomic> + +// template <class T> +// void +// atomic_init(volatile atomic<T>* obj, T desr); +// +// template <class T> +// void +// atomic_init(atomic<T>* obj, T desr); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + typedef std::atomic<T> A; + A t; + std::atomic_init(&t, T(1)); + assert(t == T(1)); + volatile A vt; + std::atomic_init(&vt, T(2)); + assert(vt == T(2)); +} + +struct A +{ + int i; + + explicit A(int d = 0) noexcept {i=d;} + + friend bool operator==(const A& x, const A& y) + {return x.i == y.i;} +}; + +int main() +{ + test<A>(); + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + test<int*>(); + test<const int*>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp new file mode 100644 index 0000000000000..18a1605e2092c --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// template <class T> +// bool +// atomic_is_lock_free(const volatile atomic<T>* obj); +// +// template <class T> +// bool +// atomic_is_lock_free(const atomic<T>* obj); + +#include <atomic> + +template <class T> +void +test() +{ + typedef std::atomic<T> A; + A t; + bool b1 = std::atomic_is_lock_free(static_cast<const A*>(&t)); + volatile A vt; + bool b2 = std::atomic_is_lock_free(static_cast<const volatile A*>(&vt)); +} + +struct A +{ + char _[4]; +}; + +int main() +{ + test<A>(); + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + test<int*>(); + test<const int*>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp new file mode 100644 index 0000000000000..66918c71f1f63 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// ... assertion fails line 34 + +// <atomic> + +// template <class T> +// T +// atomic_load(const volatile atomic<T>* obj); +// +// template <class T> +// T +// atomic_load(const atomic<T>* obj); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + typedef std::atomic<T> A; + A t; + std::atomic_init(&t, T(1)); + assert(std::atomic_load(&t) == T(1)); + volatile A vt; + std::atomic_init(&vt, T(2)); + assert(std::atomic_load(&vt) == T(2)); +} + +struct A +{ + int i; + + explicit A(int d = 0) noexcept {i=d;} + + friend bool operator==(const A& x, const A& y) + {return x.i == y.i;} +}; + +int main() +{ + test<A>(); + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + test<int*>(); + test<const int*>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp new file mode 100644 index 0000000000000..5f402a9f139fe --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// ... assertion fails line 31 + +// <atomic> + +// template <class T> +// T +// atomic_load_explicit(const volatile atomic<T>* obj, memory_order m); +// +// template <class T> +// T +// atomic_load_explicit(const atomic<T>* obj, memory_order m); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + typedef std::atomic<T> A; + A t; + std::atomic_init(&t, T(1)); + assert(std::atomic_load_explicit(&t, std::memory_order_seq_cst) == T(1)); + volatile A vt; + std::atomic_init(&vt, T(2)); + assert(std::atomic_load_explicit(&vt, std::memory_order_seq_cst) == T(2)); +} + +struct A +{ + int i; + + explicit A(int d = 0) noexcept {i=d;} + + friend bool operator==(const A& x, const A& y) + {return x.i == y.i;} +}; + +int main() +{ + test<A>(); + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + test<int*>(); + test<const int*>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp new file mode 100644 index 0000000000000..2b9582b3c522b --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// ... assertion fails line 31 + +// <atomic> + +// template <class T> +// void +// atomic_store(volatile atomic<T>* obj, T desr); +// +// template <class T> +// void +// atomic_store(atomic<T>* obj, T desr); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + typedef std::atomic<T> A; + A t; + std::atomic_store(&t, T(1)); + assert(t == T(1)); + volatile A vt; + std::atomic_store(&vt, T(2)); + assert(vt == T(2)); +} + +struct A +{ + int i; + + explicit A(int d = 0) noexcept {i=d;} + + friend bool operator==(const A& x, const A& y) + {return x.i == y.i;} +}; + +int main() +{ + test<A>(); + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + test<int*>(); + test<const int*>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp new file mode 100644 index 0000000000000..8fe0c7d884219 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// ... assertion fails line 31 + +// <atomic> + +// template <class T> +// void +// atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m); +// +// template <class T> +// void +// atomic_store_explicit(atomic<T>* obj, T desr, memory_order m); + +#include <atomic> +#include <type_traits> +#include <cassert> + +template <class T> +void +test() +{ + typedef std::atomic<T> A; + A t; + std::atomic_store_explicit(&t, T(1), std::memory_order_seq_cst); + assert(t == T(1)); + volatile A vt; + std::atomic_store_explicit(&vt, T(2), std::memory_order_seq_cst); + assert(vt == T(2)); +} + +struct A +{ + int i; + + explicit A(int d = 0) noexcept {i=d;} + + friend bool operator==(const A& x, const A& y) + {return x.i == y.i;} +}; + +int main() +{ + test<A>(); + test<char>(); + test<signed char>(); + test<unsigned char>(); + test<short>(); + test<unsigned short>(); + test<int>(); + test<unsigned int>(); + test<long>(); + test<unsigned long>(); + test<long long>(); + test<unsigned long long>(); + test<wchar_t>(); +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + test<char16_t>(); + test<char32_t>(); +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + test<int*>(); + test<const int*>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp new file mode 100644 index 0000000000000..5fed691da2686 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +// #define ATOMIC_VAR_INIT(value) + +#include <atomic> +#include <type_traits> +#include <cassert> + +int main() +{ + std::atomic<int> v = ATOMIC_VAR_INIT(5); + assert(v == 5); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp new file mode 100644 index 0000000000000..0eda2338d257d --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// UNSUPPORTED: c++98, c++03 + +// <atomic> + +// constexpr atomic<T>::atomic(T value) + +#include <atomic> +#include <type_traits> +#include <cassert> + +struct UserType { + int i; + + UserType() noexcept {} + constexpr explicit UserType(int d) noexcept : i(d) {} + + friend bool operator==(const UserType& x, const UserType& y) { + return x.i == y.i; + } +}; + +template <class Tp> +void test() { + typedef std::atomic<Tp> Atomic; + static_assert(std::is_literal_type<Atomic>::value, ""); + constexpr Tp t(42); + { + constexpr Atomic a(t); + assert(a == t); + } + { + constexpr Atomic a{t}; + assert(a == t); + } + { + constexpr Atomic a = ATOMIC_VAR_INIT(t); + assert(a == t); + } +} + + +int main() +{ + test<int>(); + test<UserType>(); +} diff --git a/test/std/atomics/atomics.types.operations/atomics.types.operations.templ/nothing_to_do.pass.cpp b/test/std/atomics/atomics.types.operations/atomics.types.operations.templ/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..9a59227abdd98 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/atomics.types.operations.templ/nothing_to_do.pass.cpp @@ -0,0 +1,13 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/atomics/atomics.types.operations/nothing_to_do.pass.cpp b/test/std/atomics/atomics.types.operations/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..9a59227abdd98 --- /dev/null +++ b/test/std/atomics/atomics.types.operations/nothing_to_do.pass.cpp @@ -0,0 +1,13 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/atomics/libcpp-has-no-threads.fail.cpp b/test/std/atomics/libcpp-has-no-threads.fail.cpp new file mode 100644 index 0000000000000..fe95e6a5983a0 --- /dev/null +++ b/test/std/atomics/libcpp-has-no-threads.fail.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <atomic> + +// Test that including <atomic> fails to compile when _LIBCPP_HAS_NO_THREADS +// is defined. + +#ifndef _LIBCPP_HAS_NO_THREADS +#define _LIBCPP_HAS_NO_THREADS +#endif + +#include <atomic> + +int main() +{ +} diff --git a/test/std/atomics/libcpp-has-no-threads.pass.cpp b/test/std/atomics/libcpp-has-no-threads.pass.cpp new file mode 100644 index 0000000000000..9c0cccbda380d --- /dev/null +++ b/test/std/atomics/libcpp-has-no-threads.pass.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// XFAIL: libcpp-has-no-threads + +#ifdef _LIBCPP_HAS_NO_THREADS +#error This should be XFAIL'd for the purpose of detecting that the LIT feature\ + 'libcpp-has-no-threads' is available iff _LIBCPP_HAS_NO_THREADS is defined +#endif + +int main() +{ +} diff --git a/test/std/atomics/version.pass.cpp b/test/std/atomics/version.pass.cpp new file mode 100644 index 0000000000000..fae2736d229f2 --- /dev/null +++ b/test/std/atomics/version.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <atomic> + +#include <atomic> + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() +{ +} |