summaryrefslogtreecommitdiff
path: root/test/std/atomics
diff options
context:
space:
mode:
Diffstat (limited to 'test/std/atomics')
-rw-r--r--test/std/atomics/atomics.fences/atomic_signal_fence.pass.cpp21
-rw-r--r--test/std/atomics/atomics.fences/atomic_thread_fence.pass.cpp21
-rw-r--r--test/std/atomics/atomics.flag/atomic_flag_clear.pass.cpp36
-rw-r--r--test/std/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp60
-rw-r--r--test/std/atomics/atomics.flag/atomic_flag_test_and_set.pass.cpp36
-rw-r--r--test/std/atomics/atomics.flag/atomic_flag_test_and_set_explicit.pass.cpp96
-rw-r--r--test/std/atomics/atomics.flag/clear.pass.cpp72
-rw-r--r--test/std/atomics/atomics.flag/copy_assign.fail.cpp24
-rw-r--r--test/std/atomics/atomics.flag/copy_ctor.fail.cpp23
-rw-r--r--test/std/atomics/atomics.flag/copy_volatile_assign.fail.cpp24
-rw-r--r--test/std/atomics/atomics.flag/default.pass.cpp33
-rw-r--r--test/std/atomics/atomics.flag/init.pass.cpp25
-rw-r--r--test/std/atomics/atomics.flag/test_and_set.pass.cpp108
-rw-r--r--test/std/atomics/atomics.general/nothing_to_do.pass.cpp13
-rw-r--r--test/std/atomics/atomics.general/replace_failure_order.pass.cpp43
-rw-r--r--test/std/atomics/atomics.lockfree/lockfree.pass.cpp52
-rw-r--r--test/std/atomics/atomics.order/kill_dependency.pass.cpp23
-rw-r--r--test/std/atomics/atomics.order/memory_order.pass.cpp33
-rw-r--r--test/std/atomics/atomics.syn/nothing_to_do.pass.cpp13
-rw-r--r--test/std/atomics/atomics.types.generic/address.pass.cpp140
-rw-r--r--test/std/atomics/atomics.types.generic/bool.pass.cpp237
-rw-r--r--test/std/atomics/atomics.types.generic/cstdint_typedefs.pass.cpp69
-rw-r--r--test/std/atomics/atomics.types.generic/integral.pass.cpp203
-rw-r--r--test/std/atomics/atomics.types.generic/integral_typedefs.pass.cpp50
-rw-r--r--test/std/atomics/atomics.types.generic/trivially_copyable.fail.cpp70
-rw-r--r--test/std/atomics/atomics.types.generic/trivially_copyable.pass.cpp77
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.arith/nothing_to_do.pass.cpp13
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.general/nothing_to_do.pass.cpp13
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.pointer/nothing_to_do.pass.cpp13
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp88
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp95
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp90
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp97
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp73
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp75
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp111
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp115
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp64
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp66
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp64
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp66
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp111
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp116
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp64
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp66
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp71
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp61
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp71
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp71
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp71
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp71
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_var_init.pass.cpp24
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp56
-rw-r--r--test/std/atomics/atomics.types.operations/atomics.types.operations.templ/nothing_to_do.pass.cpp13
-rw-r--r--test/std/atomics/atomics.types.operations/nothing_to_do.pass.cpp13
-rw-r--r--test/std/atomics/libcpp-has-no-threads.fail.cpp23
-rw-r--r--test/std/atomics/libcpp-has-no-threads.pass.cpp18
-rw-r--r--test/std/atomics/version.pass.cpp22
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()
+{
+}