Patchwork [C11-atomic] stdatomic.h fixes and tests

login
register
mail settings
Submitter Joseph S. Myers
Date Nov. 8, 2013, 9:01 p.m.
Message ID <Pine.LNX.4.64.1311082059480.14552@digraph.polyomino.org.uk>
Download mbox | patch
Permalink /patch/289915/
State New
Headers show

Comments

Joseph S. Myers - Nov. 8, 2013, 9:01 p.m.
I've applied this patch to C11-atomic branch to clean up the contents
of stdatomic.h (including renaming temporary variables in statement
expressions to include the name of the macro, or part thereof -
calling everything __tmp risks confusing bugs if some other
implementation macro calls one of these macros with an argument being
the caller's __tmp) and add test coverage for this header (largely based
on the existing tests for __atomic_* built-in functions).

There are still corner case bugs where the pointer argument to a macro
is of variably modified type (for example, pointer to atomic pointer
to VLA) and has side effects - typeof evaluates its operand if that
has variably modified type, with the result that side effects occur
twice.  I plan to address that by implementing a subset of C++11 auto
for GNU C (using a new keyword __auto_type, and only accepting forms
such as "__auto_type var = initializer;" not with more complicated
declarators such as "__auto_type *var = initializer;"); such an
extension is more generally useful whenever defining type-generic
macros with temporary variables inside statement expressions, as even
when the issue of variably modified types doesn't arise, "typeof
(macro_arg) tmp = (macro_arg);" results in a macro expansion over
twice the size of the argument text, and if calls to such macros get
used in arguments to such macros, the size of the expansion the
preprocessor needs to generate and the front end needs to parse
rapidly blows up.  However, I intend to put stdatomic.h plus testcases
on trunk before dealing with this corner case there.

gcc:
2013-11-08  Joseph Myers  <joseph@codesourcery.com>

	* ginclude/stdatomic.h: Reformat contents of file.  Include macro
	names in names of local temporaries.
	(memory_order): Do not use enum tag.
	(atomic_init): Use do { } while (0).
	(atomic_thread_fence, atomic_signal_fence): Make function-like
	macros.
	(atomic_is_lock_free): Pass object pointer to
	__atomic_is_lock_free.
	(__atomic_type_lock_free): New macro.
	(ATOMIC_BOOL_LOCK_FREE, ATOMIC_CHAR_LOCK_FREE)
	(ATOMIC_CHAR16_T_LOCK_FREE, ATOMIC_CHAR32_T_LOCK_FREE)
	(ATOMIC_WCHAR_T_LOCK_FREE, ATOMIC_SHORT_LOCK_FREE)
	(ATOMIC_INT_LOCK_FREE, ATOMIC_LONG_LOCK_FREE)
	(ATOMIC_LLONG_LOCK_FREE, ATOMIC_POINTER_LOCK_FREE): Define using
	__atomic_type_lock_free.
	(atomic_load_explicit): Use given memory order, not
	__ATOMIC_SEQ_CST.
	(atomic_exchange_explicit): Use __atomic_exchange with pointer to
	temporary for value.
	(atomic_compare_exchange_strong_explicit)
	(atomic_compare_exchange_weak_explicit): Use
	__atomic_compare_exchange.
	(atomic_flag): Make into a structure type.
	(ATOMIC_FLAG_INIT): Use braced initializer.
	(atomic_flag_test_and_set, atomic_flag_test_and_set_explicit): Use
	__atomic_test_and_set.
	(atomic_flag_clear, atomic_flag_clear_explicit): Use
	__atomic_clear.

gcc/testsuite:
2013-11-08  Joseph Myers  <joseph@codesourcery.com>

	* gcc.dg/atomic/stdatomic-compare-exchange-1.c,
	gcc.dg/atomic/stdatomic-compare-exchange-2.c,
	gcc.dg/atomic/stdatomic-compare-exchange-3.c,
	gcc.dg/atomic/stdatomic-compare-exchange-4.c,
	gcc.dg/atomic/stdatomic-exchange-1.c,
	gcc.dg/atomic/stdatomic-exchange-2.c,
	gcc.dg/atomic/stdatomic-exchange-3.c,
	gcc.dg/atomic/stdatomic-exchange-4.c,
	gcc.dg/atomic/stdatomic-fence.c, gcc.dg/atomic/stdatomic-flag.c,
	gcc.dg/atomic/stdatomic-generic.c,
	gcc.dg/atomic/stdatomic-kill-dep.c,
	gcc.dg/atomic/stdatomic-load-1.c,
	gcc.dg/atomic/stdatomic-load-2.c,
	gcc.dg/atomic/stdatomic-load-3.c,
	gcc.dg/atomic/stdatomic-load-4.c,
	gcc.dg/atomic/stdatomic-lockfree.c,
	gcc.dg/atomic/stdatomic-op-1.c, gcc.dg/atomic/stdatomic-op-2.c,
	gcc.dg/atomic/stdatomic-op-3.c, gcc.dg/atomic/stdatomic-op-4.c,
	gcc.dg/atomic/stdatomic-store-1.c,
	gcc.dg/atomic/stdatomic-store-2.c,
	gcc.dg/atomic/stdatomic-store-3.c,
	gcc.dg/atomic/stdatomic-store-4.c, gcc.dg/c11-stdatomic-1.c: New
	tests.

Patch

Index: gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-3.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-3.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-3.c	(revision 0)
@@ -0,0 +1,81 @@ 
+/* Test atomic_compare_exchange routines for existence and proper
+   execution on 2-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic int v = ATOMIC_VAR_INIT (0);
+int expected = 0;
+int max = ~0;
+int desired = ~0;
+int zero = 0;
+
+int
+main ()
+{
+
+  if (!atomic_compare_exchange_strong_explicit (&v, &expected, max, memory_order_relaxed, memory_order_relaxed))
+    abort ();
+  if (expected != 0)
+    abort ();
+
+  if (atomic_compare_exchange_strong_explicit (&v, &expected, 0, memory_order_acquire, memory_order_relaxed))
+    abort ();
+  if (expected != max)
+    abort ();
+
+  if (!atomic_compare_exchange_strong_explicit (&v, &expected, 0, memory_order_release, memory_order_acquire))
+    abort ();
+  if (expected != max)
+    abort ();
+  if (v != 0)
+    abort ();
+
+  if (atomic_compare_exchange_weak_explicit (&v, &expected, desired, memory_order_acq_rel, memory_order_acquire))
+    abort ();
+  if (expected != 0)
+    abort ();
+
+  if (!atomic_compare_exchange_strong_explicit (&v, &expected, desired, memory_order_seq_cst, memory_order_seq_cst))
+    abort ();
+  if (expected != 0)
+    abort ();
+  if (v != max)
+    abort ();
+
+  v = 0;
+
+  if (!atomic_compare_exchange_strong (&v, &expected, max))
+    abort ();
+  if (expected != 0)
+    abort ();
+
+  if (atomic_compare_exchange_strong (&v, &expected, zero))
+    abort ();
+  if (expected != max)
+    abort ();
+
+  if (!atomic_compare_exchange_strong (&v, &expected, zero))
+    abort ();
+  if (expected != max)
+    abort ();
+  if (v != 0)
+    abort ();
+
+  if (atomic_compare_exchange_weak (&v, &expected, desired))
+    abort ();
+  if (expected != 0)
+    abort ();
+
+  if (!atomic_compare_exchange_strong (&v, &expected, desired))
+    abort ();
+  if (expected != 0)
+    abort ();
+  if (v != max)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-4.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-4.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-4.c	(revision 0)
@@ -0,0 +1,81 @@ 
+/* Test atomic_compare_exchange routines for existence and proper
+   execution on 2-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic long long v = ATOMIC_VAR_INIT (0);
+long long expected = 0;
+long long max = ~0LL;
+long long desired = ~0LL;
+long long zero = 0;
+
+int
+main ()
+{
+
+  if (!atomic_compare_exchange_strong_explicit (&v, &expected, max, memory_order_relaxed, memory_order_relaxed))
+    abort ();
+  if (expected != 0)
+    abort ();
+
+  if (atomic_compare_exchange_strong_explicit (&v, &expected, 0, memory_order_acquire, memory_order_relaxed))
+    abort ();
+  if (expected != max)
+    abort ();
+
+  if (!atomic_compare_exchange_strong_explicit (&v, &expected, 0, memory_order_release, memory_order_acquire))
+    abort ();
+  if (expected != max)
+    abort ();
+  if (v != 0)
+    abort ();
+
+  if (atomic_compare_exchange_weak_explicit (&v, &expected, desired, memory_order_acq_rel, memory_order_acquire))
+    abort ();
+  if (expected != 0)
+    abort ();
+
+  if (!atomic_compare_exchange_strong_explicit (&v, &expected, desired, memory_order_seq_cst, memory_order_seq_cst))
+    abort ();
+  if (expected != 0)
+    abort ();
+  if (v != max)
+    abort ();
+
+  v = 0;
+
+  if (!atomic_compare_exchange_strong (&v, &expected, max))
+    abort ();
+  if (expected != 0)
+    abort ();
+
+  if (atomic_compare_exchange_strong (&v, &expected, zero))
+    abort ();
+  if (expected != max)
+    abort ();
+
+  if (!atomic_compare_exchange_strong (&v, &expected, zero))
+    abort ();
+  if (expected != max)
+    abort ();
+  if (v != 0)
+    abort ();
+
+  if (atomic_compare_exchange_weak (&v, &expected, desired))
+    abort ();
+  if (expected != 0)
+    abort ();
+
+  if (!atomic_compare_exchange_strong (&v, &expected, desired))
+    abort ();
+  if (expected != 0)
+    abort ();
+  if (v != max)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-store-1.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-store-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-store-1.c	(revision 0)
@@ -0,0 +1,43 @@ 
+/* Test atomic_store routines for existence and proper execution on
+   1-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic char v;
+char count;
+
+int
+main ()
+{
+  v = 0;
+  count = 0;
+
+  atomic_init (&v, count + 1);
+  if (v != ++count)
+    abort ();
+
+  atomic_store_explicit (&v, count + 1, memory_order_relaxed);
+  if (v != ++count)
+    abort ();
+
+  atomic_store_explicit (&v, count + 1, memory_order_release);
+  if (v != ++count)
+    abort ();
+
+  atomic_store_explicit (&v, count + 1, memory_order_seq_cst);
+  if (v != ++count)
+    abort ();
+
+  count++;
+
+  atomic_store (&v, count);
+  if (v != count)
+    abort ();
+
+  return 0;
+}
+
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-store-2.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-store-2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-store-2.c	(revision 0)
@@ -0,0 +1,43 @@ 
+/* Test atomic_store routines for existence and proper execution on
+   2-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic short v;
+short count;
+
+int
+main ()
+{
+  v = 0;
+  count = 0;
+
+  atomic_init (&v, count + 1);
+  if (v != ++count)
+    abort ();
+
+  atomic_store_explicit (&v, count + 1, memory_order_relaxed);
+  if (v != ++count)
+    abort ();
+
+  atomic_store_explicit (&v, count + 1, memory_order_release);
+  if (v != ++count)
+    abort ();
+
+  atomic_store_explicit (&v, count + 1, memory_order_seq_cst);
+  if (v != ++count)
+    abort ();
+
+  count++;
+
+  atomic_store (&v, count);
+  if (v != count)
+    abort ();
+
+  return 0;
+}
+
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-store-3.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-store-3.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-store-3.c	(revision 0)
@@ -0,0 +1,43 @@ 
+/* Test atomic_store routines for existence and proper execution on
+   4-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic int v;
+int count;
+
+int
+main ()
+{
+  v = 0;
+  count = 0;
+
+  atomic_init (&v, count + 1);
+  if (v != ++count)
+    abort ();
+
+  atomic_store_explicit (&v, count + 1, memory_order_relaxed);
+  if (v != ++count)
+    abort ();
+
+  atomic_store_explicit (&v, count + 1, memory_order_release);
+  if (v != ++count)
+    abort ();
+
+  atomic_store_explicit (&v, count + 1, memory_order_seq_cst);
+  if (v != ++count)
+    abort ();
+
+  count++;
+
+  atomic_store (&v, count);
+  if (v != count)
+    abort ();
+
+  return 0;
+}
+
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-store-4.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-store-4.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-store-4.c	(revision 0)
@@ -0,0 +1,43 @@ 
+/* Test atomic_store routines for existence and proper execution on
+   8-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic long long v;
+long long count;
+
+int
+main ()
+{
+  v = 0;
+  count = 0;
+
+  atomic_init (&v, count + 1);
+  if (v != ++count)
+    abort ();
+
+  atomic_store_explicit (&v, count + 1, memory_order_relaxed);
+  if (v != ++count)
+    abort ();
+
+  atomic_store_explicit (&v, count + 1, memory_order_release);
+  if (v != ++count)
+    abort ();
+
+  atomic_store_explicit (&v, count + 1, memory_order_seq_cst);
+  if (v != ++count)
+    abort ();
+
+  count++;
+
+  atomic_store (&v, count);
+  if (v != count)
+    abort ();
+
+  return 0;
+}
+
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-kill-dep.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-kill-dep.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-kill-dep.c	(revision 0)
@@ -0,0 +1,19 @@ 
+/* Test atomic_kill_dependency.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic int a = ATOMIC_VAR_INIT (1), b;
+
+int
+main ()
+{
+  b = kill_dependency (a);
+  if (b != 1)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-flag.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-flag.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-flag.c	(revision 0)
@@ -0,0 +1,38 @@ 
+/* Test atomic_flag routines for existence and execution.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+atomic_flag a = ATOMIC_FLAG_INIT;
+
+int
+main ()
+{
+  int b;
+
+  if (!atomic_is_lock_free (&a))
+    abort ();
+
+  if (atomic_flag_test_and_set (&a))
+    abort ();
+  atomic_flag_clear_explicit (&a, memory_order_relaxed);
+  if (atomic_flag_test_and_set (&a))
+    abort ();
+  atomic_flag_clear (&a);
+
+  b = atomic_flag_test_and_set_explicit (&a, memory_order_seq_cst);
+  if (!atomic_flag_test_and_set (&a) || b != 0)
+    abort ();
+
+  b = atomic_flag_test_and_set_explicit (&a, memory_order_acq_rel);
+  if (!atomic_flag_test_and_set (&a) || b != 1)
+    abort ();
+
+  atomic_flag_clear_explicit (&a, memory_order_seq_cst);
+  if (atomic_flag_test_and_set (&a))
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-op-1.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-op-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-op-1.c	(revision 0)
@@ -0,0 +1,341 @@ 
+/* Test atomic_fetch routines for existence and proper execution on
+   1-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic char v;
+char count, res;
+const char init = ~0;
+
+void
+test_fetch_add ()
+{
+  v = 0;
+  count = 1;
+
+  if (atomic_fetch_add_explicit (&v, count, memory_order_relaxed) != 0)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, 1, memory_order_consume) != 1)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, count, memory_order_acquire) != 2)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, 1, memory_order_release) != 3)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, count, memory_order_acq_rel) != 4)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, 1, memory_order_seq_cst) != 5)
+    abort ();
+
+  if (atomic_fetch_add (&v, 1) != 6)
+    abort ();
+}
+
+void
+test_fetch_sub ()
+{
+  v = res = 20;
+  count = 0;
+
+  if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_relaxed) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, 1, memory_order_consume) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acquire) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, 1, memory_order_release) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acq_rel) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, 1, memory_order_seq_cst) != res--)
+    abort ();
+
+  if (atomic_fetch_sub (&v, 1) != res--)
+    abort ();
+}
+
+void
+test_fetch_and ()
+{
+  v = init;
+
+  if (atomic_fetch_and_explicit (&v, 0, memory_order_relaxed) != init)
+    abort ();
+
+  if (atomic_fetch_and_explicit (&v, init, memory_order_consume) != 0)
+    abort ();
+
+  if (atomic_fetch_and_explicit (&v, 0, memory_order_acquire) != 0)
+    abort ();
+
+  v = ~v;
+  if (atomic_fetch_and_explicit (&v, init, memory_order_release) != init)
+    abort ();
+
+  if (atomic_fetch_and_explicit (&v, 0, memory_order_acq_rel) != init)
+    abort ();
+
+  if (atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst) != 0)
+    abort ();
+
+  if (atomic_fetch_and (&v, 0) != 0)
+    abort ();
+}
+
+void
+test_fetch_xor ()
+{
+  v = init;
+  count = 0;
+
+  if (atomic_fetch_xor_explicit (&v, count, memory_order_relaxed) != init)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, ~count, memory_order_consume) != init)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, 0, memory_order_acquire) != 0)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, ~count, memory_order_release) != 0)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel) != init)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, ~count, memory_order_seq_cst) != init)
+    abort ();
+
+  if (atomic_fetch_xor (&v, ~count) != 0)
+    abort ();
+}
+
+void
+test_fetch_or ()
+{
+  v = 0;
+  count = 1;
+
+  if (atomic_fetch_or_explicit (&v, count, memory_order_relaxed) != 0)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, 2, memory_order_consume) != 1)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, count, memory_order_acquire) != 3)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, 8, memory_order_release) != 7)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, count, memory_order_acq_rel) != 15)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, count, memory_order_seq_cst) != 31)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or (&v, count) != 63)
+    abort ();
+}
+
+
+/* Test the OP routines with a result which isn't used.  */
+
+void
+test_add ()
+{
+  v = 0;
+  count = 1;
+
+  atomic_fetch_add (&v, count);
+  if (v != 1)
+    abort ();
+
+  atomic_fetch_add_explicit (&v, count, memory_order_consume);
+  if (v != 2)
+    abort ();
+
+  atomic_fetch_add (&v, 1);
+  if (v != 3)
+    abort ();
+
+  atomic_fetch_add_explicit (&v, 1, memory_order_release);
+  if (v != 4)
+    abort ();
+
+  atomic_fetch_add (&v, 1);
+  if (v != 5)
+    abort ();
+
+  atomic_fetch_add_explicit (&v, count, memory_order_seq_cst);
+  if (v != 6)
+    abort ();
+}
+
+void
+test_sub ()
+{
+  v = res = 20;
+  count = 0;
+
+  atomic_fetch_sub (&v, count + 1);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub_explicit (&v, count + 1, memory_order_consume);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub (&v, 1);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub_explicit (&v, 1, memory_order_release);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub (&v, count + 1);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub_explicit (&v, count + 1, memory_order_seq_cst);
+  if (v != --res)
+    abort ();
+}
+
+void
+test_and ()
+{
+  v = init;
+
+  atomic_fetch_and (&v, 0);
+  if (v != 0)
+    abort ();
+
+  v = init;
+  atomic_fetch_and_explicit (&v, init, memory_order_consume);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_and (&v, 0);
+  if (v != 0)
+    abort ();
+
+  v = ~v;
+  atomic_fetch_and_explicit (&v, init, memory_order_release);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_and (&v, 0);
+  if (v != 0)
+    abort ();
+
+  v = ~v;
+  atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst);
+  if (v != 0)
+    abort ();
+}
+
+void
+test_xor ()
+{
+  v = init;
+  count = 0;
+
+  atomic_fetch_xor (&v, count);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_xor_explicit (&v, ~count, memory_order_consume);
+  if (v != 0)
+    abort ();
+
+  atomic_fetch_xor (&v, 0);
+  if (v != 0)
+    abort ();
+
+  atomic_fetch_xor_explicit (&v, ~count, memory_order_release);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_xor (&v, ~count);
+  if (v != 0)
+    abort ();
+}
+
+void
+test_or ()
+{
+  v = 0;
+  count = 1;
+
+  atomic_fetch_or (&v, count);
+  if (v != 1)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or_explicit (&v, count, memory_order_consume);
+  if (v != 3)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or (&v, 4);
+  if (v != 7)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or_explicit (&v, 8, memory_order_release);
+  if (v != 15)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or (&v, count);
+  if (v != 31)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or_explicit (&v, count, memory_order_seq_cst);
+  if (v != 63)
+    abort ();
+}
+
+int
+main ()
+{
+  test_fetch_add ();
+  test_fetch_sub ();
+  test_fetch_and ();
+  test_fetch_xor ();
+  test_fetch_or ();
+
+  test_add ();
+  test_sub ();
+  test_and ();
+  test_xor ();
+  test_or ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-generic.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-generic.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-generic.c	(revision 0)
@@ -0,0 +1,52 @@ 
+/* Test generic atomic routines for proper function calling.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort ();
+extern int memcmp (const void *, const void *, __SIZE_TYPE__);
+
+typedef struct test {
+  int array[10];
+} test_struct;
+
+test_struct zero = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+test_struct ones = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+_Atomic test_struct a;
+test_struct b;
+
+int size = sizeof (test_struct);
+/* Test for consistency on sizes 1, 2, 4, 8, 16 and 32.  */
+int
+main ()
+{
+  test_struct c;
+
+  atomic_store_explicit (&a, zero, memory_order_relaxed);
+  if (memcmp (&a, &zero, size))
+    abort ();
+
+  c = atomic_exchange_explicit (&a, ones, memory_order_seq_cst);
+  if (memcmp (&c, &zero, size))
+    abort ();
+  if (memcmp (&a, &ones, size))
+    abort ();
+
+  b = atomic_load_explicit (&a, memory_order_relaxed);
+  if (memcmp (&b, &ones, size))
+    abort ();
+
+  if (!atomic_compare_exchange_strong_explicit (&a, &b, zero, memory_order_seq_cst, memory_order_acquire))
+    abort ();
+  if (memcmp (&a, &zero, size))
+    abort ();
+
+  if (atomic_compare_exchange_weak_explicit (&a, &b, ones, memory_order_seq_cst, memory_order_acquire))
+    abort ();
+  if (memcmp (&b, &zero, size))
+    abort ();
+
+  return 0;
+}
+
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-op-2.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-op-2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-op-2.c	(revision 0)
@@ -0,0 +1,341 @@ 
+/* Test atomic_fetch routines for existence and proper execution on
+   2-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic short v;
+short count, res;
+const short init = ~0;
+
+void
+test_fetch_add ()
+{
+  v = 0;
+  count = 1;
+
+  if (atomic_fetch_add_explicit (&v, count, memory_order_relaxed) != 0)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, 1, memory_order_consume) != 1)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, count, memory_order_acquire) != 2)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, 1, memory_order_release) != 3)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, count, memory_order_acq_rel) != 4)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, 1, memory_order_seq_cst) != 5)
+    abort ();
+
+  if (atomic_fetch_add (&v, 1) != 6)
+    abort ();
+}
+
+void
+test_fetch_sub ()
+{
+  v = res = 20;
+  count = 0;
+
+  if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_relaxed) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, 1, memory_order_consume) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acquire) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, 1, memory_order_release) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acq_rel) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, 1, memory_order_seq_cst) != res--)
+    abort ();
+
+  if (atomic_fetch_sub (&v, 1) != res--)
+    abort ();
+}
+
+void
+test_fetch_and ()
+{
+  v = init;
+
+  if (atomic_fetch_and_explicit (&v, 0, memory_order_relaxed) != init)
+    abort ();
+
+  if (atomic_fetch_and_explicit (&v, init, memory_order_consume) != 0)
+    abort ();
+
+  if (atomic_fetch_and_explicit (&v, 0, memory_order_acquire) != 0)
+    abort ();
+
+  v = ~v;
+  if (atomic_fetch_and_explicit (&v, init, memory_order_release) != init)
+    abort ();
+
+  if (atomic_fetch_and_explicit (&v, 0, memory_order_acq_rel) != init)
+    abort ();
+
+  if (atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst) != 0)
+    abort ();
+
+  if (atomic_fetch_and (&v, 0) != 0)
+    abort ();
+}
+
+void
+test_fetch_xor ()
+{
+  v = init;
+  count = 0;
+
+  if (atomic_fetch_xor_explicit (&v, count, memory_order_relaxed) != init)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, ~count, memory_order_consume) != init)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, 0, memory_order_acquire) != 0)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, ~count, memory_order_release) != 0)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel) != init)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, ~count, memory_order_seq_cst) != init)
+    abort ();
+
+  if (atomic_fetch_xor (&v, ~count) != 0)
+    abort ();
+}
+
+void
+test_fetch_or ()
+{
+  v = 0;
+  count = 1;
+
+  if (atomic_fetch_or_explicit (&v, count, memory_order_relaxed) != 0)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, 2, memory_order_consume) != 1)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, count, memory_order_acquire) != 3)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, 8, memory_order_release) != 7)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, count, memory_order_acq_rel) != 15)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, count, memory_order_seq_cst) != 31)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or (&v, count) != 63)
+    abort ();
+}
+
+
+/* Test the OP routines with a result which isn't used.  */
+
+void
+test_add ()
+{
+  v = 0;
+  count = 1;
+
+  atomic_fetch_add (&v, count);
+  if (v != 1)
+    abort ();
+
+  atomic_fetch_add_explicit (&v, count, memory_order_consume);
+  if (v != 2)
+    abort ();
+
+  atomic_fetch_add (&v, 1);
+  if (v != 3)
+    abort ();
+
+  atomic_fetch_add_explicit (&v, 1, memory_order_release);
+  if (v != 4)
+    abort ();
+
+  atomic_fetch_add (&v, 1);
+  if (v != 5)
+    abort ();
+
+  atomic_fetch_add_explicit (&v, count, memory_order_seq_cst);
+  if (v != 6)
+    abort ();
+}
+
+void
+test_sub ()
+{
+  v = res = 20;
+  count = 0;
+
+  atomic_fetch_sub (&v, count + 1);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub_explicit (&v, count + 1, memory_order_consume);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub (&v, 1);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub_explicit (&v, 1, memory_order_release);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub (&v, count + 1);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub_explicit (&v, count + 1, memory_order_seq_cst);
+  if (v != --res)
+    abort ();
+}
+
+void
+test_and ()
+{
+  v = init;
+
+  atomic_fetch_and (&v, 0);
+  if (v != 0)
+    abort ();
+
+  v = init;
+  atomic_fetch_and_explicit (&v, init, memory_order_consume);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_and (&v, 0);
+  if (v != 0)
+    abort ();
+
+  v = ~v;
+  atomic_fetch_and_explicit (&v, init, memory_order_release);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_and (&v, 0);
+  if (v != 0)
+    abort ();
+
+  v = ~v;
+  atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst);
+  if (v != 0)
+    abort ();
+}
+
+void
+test_xor ()
+{
+  v = init;
+  count = 0;
+
+  atomic_fetch_xor (&v, count);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_xor_explicit (&v, ~count, memory_order_consume);
+  if (v != 0)
+    abort ();
+
+  atomic_fetch_xor (&v, 0);
+  if (v != 0)
+    abort ();
+
+  atomic_fetch_xor_explicit (&v, ~count, memory_order_release);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_xor (&v, ~count);
+  if (v != 0)
+    abort ();
+}
+
+void
+test_or ()
+{
+  v = 0;
+  count = 1;
+
+  atomic_fetch_or (&v, count);
+  if (v != 1)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or_explicit (&v, count, memory_order_consume);
+  if (v != 3)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or (&v, 4);
+  if (v != 7)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or_explicit (&v, 8, memory_order_release);
+  if (v != 15)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or (&v, count);
+  if (v != 31)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or_explicit (&v, count, memory_order_seq_cst);
+  if (v != 63)
+    abort ();
+}
+
+int
+main ()
+{
+  test_fetch_add ();
+  test_fetch_sub ();
+  test_fetch_and ();
+  test_fetch_xor ();
+  test_fetch_or ();
+
+  test_add ();
+  test_sub ();
+  test_and ();
+  test_xor ();
+  test_or ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-load-1.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-load-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-load-1.c	(revision 0)
@@ -0,0 +1,44 @@ 
+/* Test atomic_load routines for existence and proper execution on
+   1-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic char v;
+char count;
+
+int
+main ()
+{
+  v = 0;
+  count = 0;
+
+  if (atomic_load_explicit (&v, memory_order_relaxed) != count++)
+    abort ();
+  else
+    v++;
+
+  if (atomic_load_explicit (&v, memory_order_acquire) != count++)
+    abort ();
+  else
+    v++;
+
+  if (atomic_load_explicit (&v, memory_order_consume) != count++)
+    abort ();
+  else
+    v++;
+
+  if (atomic_load_explicit (&v, memory_order_seq_cst) != count++)
+    abort ();
+  else
+    v++;
+
+  if (atomic_load (&v) != count)
+    abort ();
+
+  return 0;
+}
+
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-op-3.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-op-3.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-op-3.c	(revision 0)
@@ -0,0 +1,341 @@ 
+/* Test atomic_fetch routines for existence and proper execution on
+   4-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic int v;
+int count, res;
+const int init = ~0;
+
+void
+test_fetch_add ()
+{
+  v = 0;
+  count = 1;
+
+  if (atomic_fetch_add_explicit (&v, count, memory_order_relaxed) != 0)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, 1, memory_order_consume) != 1)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, count, memory_order_acquire) != 2)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, 1, memory_order_release) != 3)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, count, memory_order_acq_rel) != 4)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, 1, memory_order_seq_cst) != 5)
+    abort ();
+
+  if (atomic_fetch_add (&v, 1) != 6)
+    abort ();
+}
+
+void
+test_fetch_sub ()
+{
+  v = res = 20;
+  count = 0;
+
+  if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_relaxed) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, 1, memory_order_consume) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acquire) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, 1, memory_order_release) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acq_rel) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, 1, memory_order_seq_cst) != res--)
+    abort ();
+
+  if (atomic_fetch_sub (&v, 1) != res--)
+    abort ();
+}
+
+void
+test_fetch_and ()
+{
+  v = init;
+
+  if (atomic_fetch_and_explicit (&v, 0, memory_order_relaxed) != init)
+    abort ();
+
+  if (atomic_fetch_and_explicit (&v, init, memory_order_consume) != 0)
+    abort ();
+
+  if (atomic_fetch_and_explicit (&v, 0, memory_order_acquire) != 0)
+    abort ();
+
+  v = ~v;
+  if (atomic_fetch_and_explicit (&v, init, memory_order_release) != init)
+    abort ();
+
+  if (atomic_fetch_and_explicit (&v, 0, memory_order_acq_rel) != init)
+    abort ();
+
+  if (atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst) != 0)
+    abort ();
+
+  if (atomic_fetch_and (&v, 0) != 0)
+    abort ();
+}
+
+void
+test_fetch_xor ()
+{
+  v = init;
+  count = 0;
+
+  if (atomic_fetch_xor_explicit (&v, count, memory_order_relaxed) != init)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, ~count, memory_order_consume) != init)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, 0, memory_order_acquire) != 0)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, ~count, memory_order_release) != 0)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel) != init)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, ~count, memory_order_seq_cst) != init)
+    abort ();
+
+  if (atomic_fetch_xor (&v, ~count) != 0)
+    abort ();
+}
+
+void
+test_fetch_or ()
+{
+  v = 0;
+  count = 1;
+
+  if (atomic_fetch_or_explicit (&v, count, memory_order_relaxed) != 0)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, 2, memory_order_consume) != 1)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, count, memory_order_acquire) != 3)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, 8, memory_order_release) != 7)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, count, memory_order_acq_rel) != 15)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, count, memory_order_seq_cst) != 31)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or (&v, count) != 63)
+    abort ();
+}
+
+
+/* Test the OP routines with a result which isn't used.  */
+
+void
+test_add ()
+{
+  v = 0;
+  count = 1;
+
+  atomic_fetch_add (&v, count);
+  if (v != 1)
+    abort ();
+
+  atomic_fetch_add_explicit (&v, count, memory_order_consume);
+  if (v != 2)
+    abort ();
+
+  atomic_fetch_add (&v, 1);
+  if (v != 3)
+    abort ();
+
+  atomic_fetch_add_explicit (&v, 1, memory_order_release);
+  if (v != 4)
+    abort ();
+
+  atomic_fetch_add (&v, 1);
+  if (v != 5)
+    abort ();
+
+  atomic_fetch_add_explicit (&v, count, memory_order_seq_cst);
+  if (v != 6)
+    abort ();
+}
+
+void
+test_sub ()
+{
+  v = res = 20;
+  count = 0;
+
+  atomic_fetch_sub (&v, count + 1);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub_explicit (&v, count + 1, memory_order_consume);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub (&v, 1);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub_explicit (&v, 1, memory_order_release);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub (&v, count + 1);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub_explicit (&v, count + 1, memory_order_seq_cst);
+  if (v != --res)
+    abort ();
+}
+
+void
+test_and ()
+{
+  v = init;
+
+  atomic_fetch_and (&v, 0);
+  if (v != 0)
+    abort ();
+
+  v = init;
+  atomic_fetch_and_explicit (&v, init, memory_order_consume);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_and (&v, 0);
+  if (v != 0)
+    abort ();
+
+  v = ~v;
+  atomic_fetch_and_explicit (&v, init, memory_order_release);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_and (&v, 0);
+  if (v != 0)
+    abort ();
+
+  v = ~v;
+  atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst);
+  if (v != 0)
+    abort ();
+}
+
+void
+test_xor ()
+{
+  v = init;
+  count = 0;
+
+  atomic_fetch_xor (&v, count);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_xor_explicit (&v, ~count, memory_order_consume);
+  if (v != 0)
+    abort ();
+
+  atomic_fetch_xor (&v, 0);
+  if (v != 0)
+    abort ();
+
+  atomic_fetch_xor_explicit (&v, ~count, memory_order_release);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_xor (&v, ~count);
+  if (v != 0)
+    abort ();
+}
+
+void
+test_or ()
+{
+  v = 0;
+  count = 1;
+
+  atomic_fetch_or (&v, count);
+  if (v != 1)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or_explicit (&v, count, memory_order_consume);
+  if (v != 3)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or (&v, 4);
+  if (v != 7)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or_explicit (&v, 8, memory_order_release);
+  if (v != 15)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or (&v, count);
+  if (v != 31)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or_explicit (&v, count, memory_order_seq_cst);
+  if (v != 63)
+    abort ();
+}
+
+int
+main ()
+{
+  test_fetch_add ();
+  test_fetch_sub ();
+  test_fetch_and ();
+  test_fetch_xor ();
+  test_fetch_or ();
+
+  test_add ();
+  test_sub ();
+  test_and ();
+  test_xor ();
+  test_or ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-load-2.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-load-2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-load-2.c	(revision 0)
@@ -0,0 +1,44 @@ 
+/* Test atomic_load routines for existence and proper execution on
+   2-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic short v;
+short count;
+
+int
+main ()
+{
+  v = 0;
+  count = 0;
+
+  if (atomic_load_explicit (&v, memory_order_relaxed) != count++)
+    abort ();
+  else
+    v++;
+
+  if (atomic_load_explicit (&v, memory_order_acquire) != count++)
+    abort ();
+  else
+    v++;
+
+  if (atomic_load_explicit (&v, memory_order_consume) != count++)
+    abort ();
+  else
+    v++;
+
+  if (atomic_load_explicit (&v, memory_order_seq_cst) != count++)
+    abort ();
+  else
+    v++;
+
+  if (atomic_load (&v) != count)
+    abort ();
+
+  return 0;
+}
+
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-load-3.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-load-3.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-load-3.c	(revision 0)
@@ -0,0 +1,44 @@ 
+/* Test atomic_load routines for existence and proper execution on
+   4-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic int v;
+int count;
+
+int
+main ()
+{
+  v = 0;
+  count = 0;
+
+  if (atomic_load_explicit (&v, memory_order_relaxed) != count++)
+    abort ();
+  else
+    v++;
+
+  if (atomic_load_explicit (&v, memory_order_acquire) != count++)
+    abort ();
+  else
+    v++;
+
+  if (atomic_load_explicit (&v, memory_order_consume) != count++)
+    abort ();
+  else
+    v++;
+
+  if (atomic_load_explicit (&v, memory_order_seq_cst) != count++)
+    abort ();
+  else
+    v++;
+
+  if (atomic_load (&v) != count)
+    abort ();
+
+  return 0;
+}
+
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-op-4.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-op-4.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-op-4.c	(revision 0)
@@ -0,0 +1,341 @@ 
+/* Test atomic_fetch routines for existence and proper execution on
+   8-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic long long v;
+long long count, res;
+const long long init = ~0;
+
+void
+test_fetch_add ()
+{
+  v = 0;
+  count = 1;
+
+  if (atomic_fetch_add_explicit (&v, count, memory_order_relaxed) != 0)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, 1, memory_order_consume) != 1)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, count, memory_order_acquire) != 2)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, 1, memory_order_release) != 3)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, count, memory_order_acq_rel) != 4)
+    abort ();
+
+  if (atomic_fetch_add_explicit (&v, 1, memory_order_seq_cst) != 5)
+    abort ();
+
+  if (atomic_fetch_add (&v, 1) != 6)
+    abort ();
+}
+
+void
+test_fetch_sub ()
+{
+  v = res = 20;
+  count = 0;
+
+  if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_relaxed) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, 1, memory_order_consume) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acquire) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, 1, memory_order_release) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acq_rel) != res--)
+    abort ();
+
+  if (atomic_fetch_sub_explicit (&v, 1, memory_order_seq_cst) != res--)
+    abort ();
+
+  if (atomic_fetch_sub (&v, 1) != res--)
+    abort ();
+}
+
+void
+test_fetch_and ()
+{
+  v = init;
+
+  if (atomic_fetch_and_explicit (&v, 0, memory_order_relaxed) != init)
+    abort ();
+
+  if (atomic_fetch_and_explicit (&v, init, memory_order_consume) != 0)
+    abort ();
+
+  if (atomic_fetch_and_explicit (&v, 0, memory_order_acquire) != 0)
+    abort ();
+
+  v = ~v;
+  if (atomic_fetch_and_explicit (&v, init, memory_order_release) != init)
+    abort ();
+
+  if (atomic_fetch_and_explicit (&v, 0, memory_order_acq_rel) != init)
+    abort ();
+
+  if (atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst) != 0)
+    abort ();
+
+  if (atomic_fetch_and (&v, 0) != 0)
+    abort ();
+}
+
+void
+test_fetch_xor ()
+{
+  v = init;
+  count = 0;
+
+  if (atomic_fetch_xor_explicit (&v, count, memory_order_relaxed) != init)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, ~count, memory_order_consume) != init)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, 0, memory_order_acquire) != 0)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, ~count, memory_order_release) != 0)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel) != init)
+    abort ();
+
+  if (atomic_fetch_xor_explicit (&v, ~count, memory_order_seq_cst) != init)
+    abort ();
+
+  if (atomic_fetch_xor (&v, ~count) != 0)
+    abort ();
+}
+
+void
+test_fetch_or ()
+{
+  v = 0;
+  count = 1;
+
+  if (atomic_fetch_or_explicit (&v, count, memory_order_relaxed) != 0)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, 2, memory_order_consume) != 1)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, count, memory_order_acquire) != 3)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, 8, memory_order_release) != 7)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, count, memory_order_acq_rel) != 15)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or_explicit (&v, count, memory_order_seq_cst) != 31)
+    abort ();
+
+  count *= 2;
+  if (atomic_fetch_or (&v, count) != 63)
+    abort ();
+}
+
+
+/* Test the OP routines with a result which isn't used.  */
+
+void
+test_add ()
+{
+  v = 0;
+  count = 1;
+
+  atomic_fetch_add (&v, count);
+  if (v != 1)
+    abort ();
+
+  atomic_fetch_add_explicit (&v, count, memory_order_consume);
+  if (v != 2)
+    abort ();
+
+  atomic_fetch_add (&v, 1);
+  if (v != 3)
+    abort ();
+
+  atomic_fetch_add_explicit (&v, 1, memory_order_release);
+  if (v != 4)
+    abort ();
+
+  atomic_fetch_add (&v, 1);
+  if (v != 5)
+    abort ();
+
+  atomic_fetch_add_explicit (&v, count, memory_order_seq_cst);
+  if (v != 6)
+    abort ();
+}
+
+void
+test_sub ()
+{
+  v = res = 20;
+  count = 0;
+
+  atomic_fetch_sub (&v, count + 1);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub_explicit (&v, count + 1, memory_order_consume);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub (&v, 1);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub_explicit (&v, 1, memory_order_release);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub (&v, count + 1);
+  if (v != --res)
+    abort ();
+
+  atomic_fetch_sub_explicit (&v, count + 1, memory_order_seq_cst);
+  if (v != --res)
+    abort ();
+}
+
+void
+test_and ()
+{
+  v = init;
+
+  atomic_fetch_and (&v, 0);
+  if (v != 0)
+    abort ();
+
+  v = init;
+  atomic_fetch_and_explicit (&v, init, memory_order_consume);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_and (&v, 0);
+  if (v != 0)
+    abort ();
+
+  v = ~v;
+  atomic_fetch_and_explicit (&v, init, memory_order_release);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_and (&v, 0);
+  if (v != 0)
+    abort ();
+
+  v = ~v;
+  atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst);
+  if (v != 0)
+    abort ();
+}
+
+void
+test_xor ()
+{
+  v = init;
+  count = 0;
+
+  atomic_fetch_xor (&v, count);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_xor_explicit (&v, ~count, memory_order_consume);
+  if (v != 0)
+    abort ();
+
+  atomic_fetch_xor (&v, 0);
+  if (v != 0)
+    abort ();
+
+  atomic_fetch_xor_explicit (&v, ~count, memory_order_release);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel);
+  if (v != init)
+    abort ();
+
+  atomic_fetch_xor (&v, ~count);
+  if (v != 0)
+    abort ();
+}
+
+void
+test_or ()
+{
+  v = 0;
+  count = 1;
+
+  atomic_fetch_or (&v, count);
+  if (v != 1)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or_explicit (&v, count, memory_order_consume);
+  if (v != 3)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or (&v, 4);
+  if (v != 7)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or_explicit (&v, 8, memory_order_release);
+  if (v != 15)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or (&v, count);
+  if (v != 31)
+    abort ();
+
+  count *= 2;
+  atomic_fetch_or_explicit (&v, count, memory_order_seq_cst);
+  if (v != 63)
+    abort ();
+}
+
+int
+main ()
+{
+  test_fetch_add ();
+  test_fetch_sub ();
+  test_fetch_and ();
+  test_fetch_xor ();
+  test_fetch_or ();
+
+  test_add ();
+  test_sub ();
+  test_and ();
+  test_xor ();
+  test_or ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-fence.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-fence.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-fence.c	(revision 0)
@@ -0,0 +1,26 @@ 
+/* Test atomic_*_fence routines for existence and execution with each
+   valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+int
+main ()
+{
+  atomic_thread_fence (memory_order_relaxed);
+  atomic_thread_fence (memory_order_consume);
+  atomic_thread_fence (memory_order_acquire);
+  atomic_thread_fence (memory_order_release);
+  atomic_thread_fence (memory_order_acq_rel);
+  atomic_thread_fence (memory_order_seq_cst);
+
+  atomic_signal_fence (memory_order_relaxed);
+  atomic_signal_fence (memory_order_consume);
+  atomic_signal_fence (memory_order_acquire);
+  atomic_signal_fence (memory_order_release);
+  atomic_signal_fence (memory_order_acq_rel);
+  atomic_signal_fence (memory_order_seq_cst);
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-load-4.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-load-4.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-load-4.c	(revision 0)
@@ -0,0 +1,44 @@ 
+/* Test atomic_load routines for existence and proper execution on
+   8-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic long long v;
+long long count;
+
+int
+main ()
+{
+  v = 0;
+  count = 0;
+
+  if (atomic_load_explicit (&v, memory_order_relaxed) != count++)
+    abort ();
+  else
+    v++;
+
+  if (atomic_load_explicit (&v, memory_order_acquire) != count++)
+    abort ();
+  else
+    v++;
+
+  if (atomic_load_explicit (&v, memory_order_consume) != count++)
+    abort ();
+  else
+    v++;
+
+  if (atomic_load_explicit (&v, memory_order_seq_cst) != count++)
+    abort ();
+  else
+    v++;
+
+  if (atomic_load (&v) != count)
+    abort ();
+
+  return 0;
+}
+
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-1.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-1.c	(revision 0)
@@ -0,0 +1,46 @@ 
+/* Test atomic_exchange routines for existence and proper execution on
+   1-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic char v;
+char count, ret;
+
+int
+main ()
+{
+  v = 0;
+  count = 0;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_relaxed) != count)
+    abort ();
+  count++;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_acquire) != count)
+    abort ();
+  count++;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_release) != count)
+    abort ();
+  count++;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_acq_rel) != count)
+    abort ();
+  count++;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_seq_cst) != count)
+    abort ();
+  count++;
+
+  count++;
+
+  ret = atomic_exchange (&v, count);
+  if (ret != count - 1 || v != count)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-2.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-2.c	(revision 0)
@@ -0,0 +1,46 @@ 
+/* Test atomic_exchange routines for existence and proper execution on
+   2-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic short v;
+short count, ret;
+
+int
+main ()
+{
+  v = 0;
+  count = 0;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_relaxed) != count)
+    abort ();
+  count++;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_acquire) != count)
+    abort ();
+  count++;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_release) != count)
+    abort ();
+  count++;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_acq_rel) != count)
+    abort ();
+  count++;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_seq_cst) != count)
+    abort ();
+  count++;
+
+  count++;
+
+  ret = atomic_exchange (&v, count);
+  if (ret != count - 1 || v != count)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-3.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-3.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-3.c	(revision 0)
@@ -0,0 +1,46 @@ 
+/* Test atomic_exchange routines for existence and proper execution on
+   4-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic int v;
+int count, ret;
+
+int
+main ()
+{
+  v = 0;
+  count = 0;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_relaxed) != count)
+    abort ();
+  count++;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_acquire) != count)
+    abort ();
+  count++;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_release) != count)
+    abort ();
+  count++;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_acq_rel) != count)
+    abort ();
+  count++;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_seq_cst) != count)
+    abort ();
+  count++;
+
+  count++;
+
+  ret = atomic_exchange (&v, count);
+  if (ret != count - 1 || v != count)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-4.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-4.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-exchange-4.c	(revision 0)
@@ -0,0 +1,46 @@ 
+/* Test atomic_exchange routines for existence and proper execution on
+   8-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic long long v;
+long long count, ret;
+
+int
+main ()
+{
+  v = 0;
+  count = 0;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_relaxed) != count)
+    abort ();
+  count++;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_acquire) != count)
+    abort ();
+  count++;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_release) != count)
+    abort ();
+  count++;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_acq_rel) != count)
+    abort ();
+  count++;
+
+  if (atomic_exchange_explicit (&v, count + 1, memory_order_seq_cst) != count)
+    abort ();
+  count++;
+
+  count++;
+
+  ret = atomic_exchange (&v, count);
+  if (ret != count - 1 || v != count)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-lockfree.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-lockfree.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-lockfree.c	(revision 0)
@@ -0,0 +1,68 @@ 
+/* Test atomic_is_lock_free.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+#include <stdint.h>
+
+extern void abort ();
+
+_Atomic _Bool aba;
+atomic_bool abt;
+_Atomic char aca;
+atomic_char act;
+_Atomic __CHAR16_TYPE__ ac16a;
+atomic_char16_t ac16t;
+_Atomic __CHAR32_TYPE__ ac32a;
+atomic_char32_t ac32t;
+_Atomic __WCHAR_TYPE__ awca;
+atomic_wchar_t awct;
+_Atomic short asa;
+atomic_short ast;
+_Atomic int aia;
+atomic_int ait;
+_Atomic long ala;
+atomic_long alt;
+_Atomic long long alla;
+atomic_llong allt;
+void *_Atomic apa;
+
+#define CHECK_TYPE(MACRO, V1, V2)		\
+  do						\
+    {						\
+      int r1 = MACRO;				\
+      int r2 = atomic_is_lock_free (&V1);	\
+      int r3 = atomic_is_lock_free (&V2);	\
+      if (r1 != 0 && r1 != 1 && r1 != 2)	\
+	abort ();				\
+      if (r2 != 0 && r2 != 1)			\
+	abort ();				\
+      if (r3 != 0 && r3 != 1)			\
+	abort ();				\
+      if (r1 == 2 && r2 != 1)			\
+	abort ();				\
+      if (r1 == 2 && r3 != 1)			\
+	abort ();				\
+      if (r1 == 0 && r2 != 0)			\
+	abort ();				\
+      if (r1 == 0 && r3 != 0)			\
+	abort ();				\
+    }						\
+  while (0)
+
+int
+main ()
+{
+  CHECK_TYPE (ATOMIC_BOOL_LOCK_FREE, aba, abt);
+  CHECK_TYPE (ATOMIC_CHAR_LOCK_FREE, aca, act);
+  CHECK_TYPE (ATOMIC_CHAR16_T_LOCK_FREE, ac16a, ac16t);
+  CHECK_TYPE (ATOMIC_CHAR32_T_LOCK_FREE, ac32a, ac32t);
+  CHECK_TYPE (ATOMIC_WCHAR_T_LOCK_FREE, awca, awct);
+  CHECK_TYPE (ATOMIC_SHORT_LOCK_FREE, asa, ast);
+  CHECK_TYPE (ATOMIC_INT_LOCK_FREE, aia, ait);
+  CHECK_TYPE (ATOMIC_LONG_LOCK_FREE, ala, alt);
+  CHECK_TYPE (ATOMIC_LLONG_LOCK_FREE, alla, allt);
+  CHECK_TYPE (ATOMIC_POINTER_LOCK_FREE, apa, apa);
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-1.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-1.c	(revision 0)
@@ -0,0 +1,81 @@ 
+/* Test atomic_compare_exchange routines for existence and proper
+   execution on 1-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic char v = ATOMIC_VAR_INIT (0);
+char expected = 0;
+char max = ~0;
+char desired = ~0;
+char zero = 0;
+
+int
+main ()
+{
+
+  if (!atomic_compare_exchange_strong_explicit (&v, &expected, max, memory_order_relaxed, memory_order_relaxed))
+    abort ();
+  if (expected != 0)
+    abort ();
+
+  if (atomic_compare_exchange_strong_explicit (&v, &expected, 0, memory_order_acquire, memory_order_relaxed))
+    abort ();
+  if (expected != max)
+    abort ();
+
+  if (!atomic_compare_exchange_strong_explicit (&v, &expected, 0, memory_order_release, memory_order_acquire))
+    abort ();
+  if (expected != max)
+    abort ();
+  if (v != 0)
+    abort ();
+
+  if (atomic_compare_exchange_weak_explicit (&v, &expected, desired, memory_order_acq_rel, memory_order_acquire))
+    abort ();
+  if (expected != 0)
+    abort ();
+
+  if (!atomic_compare_exchange_strong_explicit (&v, &expected, desired, memory_order_seq_cst, memory_order_seq_cst))
+    abort ();
+  if (expected != 0)
+    abort ();
+  if (v != max)
+    abort ();
+
+  v = 0;
+
+  if (!atomic_compare_exchange_strong (&v, &expected, max))
+    abort ();
+  if (expected != 0)
+    abort ();
+
+  if (atomic_compare_exchange_strong (&v, &expected, zero))
+    abort ();
+  if (expected != max)
+    abort ();
+
+  if (!atomic_compare_exchange_strong (&v, &expected, zero))
+    abort ();
+  if (expected != max)
+    abort ();
+  if (v != 0)
+    abort ();
+
+  if (atomic_compare_exchange_weak (&v, &expected, desired))
+    abort ();
+  if (expected != 0)
+    abort ();
+
+  if (!atomic_compare_exchange_strong (&v, &expected, desired))
+    abort ();
+  if (expected != 0)
+    abort ();
+  if (v != max)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-2.c
===================================================================
--- gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/atomic/stdatomic-compare-exchange-2.c	(revision 0)
@@ -0,0 +1,81 @@ 
+/* Test atomic_compare_exchange routines for existence and proper
+   execution on 2-byte values with each valid memory model.  */
+/* { dg-do run } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+extern void abort (void);
+
+_Atomic short v = ATOMIC_VAR_INIT (0);
+short expected = 0;
+short max = ~0;
+short desired = ~0;
+short zero = 0;
+
+int
+main ()
+{
+
+  if (!atomic_compare_exchange_strong_explicit (&v, &expected, max, memory_order_relaxed, memory_order_relaxed))
+    abort ();
+  if (expected != 0)
+    abort ();
+
+  if (atomic_compare_exchange_strong_explicit (&v, &expected, 0, memory_order_acquire, memory_order_relaxed))
+    abort ();
+  if (expected != max)
+    abort ();
+
+  if (!atomic_compare_exchange_strong_explicit (&v, &expected, 0, memory_order_release, memory_order_acquire))
+    abort ();
+  if (expected != max)
+    abort ();
+  if (v != 0)
+    abort ();
+
+  if (atomic_compare_exchange_weak_explicit (&v, &expected, desired, memory_order_acq_rel, memory_order_acquire))
+    abort ();
+  if (expected != 0)
+    abort ();
+
+  if (!atomic_compare_exchange_strong_explicit (&v, &expected, desired, memory_order_seq_cst, memory_order_seq_cst))
+    abort ();
+  if (expected != 0)
+    abort ();
+  if (v != max)
+    abort ();
+
+  v = 0;
+
+  if (!atomic_compare_exchange_strong (&v, &expected, max))
+    abort ();
+  if (expected != 0)
+    abort ();
+
+  if (atomic_compare_exchange_strong (&v, &expected, zero))
+    abort ();
+  if (expected != max)
+    abort ();
+
+  if (!atomic_compare_exchange_strong (&v, &expected, zero))
+    abort ();
+  if (expected != max)
+    abort ();
+  if (v != 0)
+    abort ();
+
+  if (atomic_compare_exchange_weak (&v, &expected, desired))
+    abort ();
+  if (expected != 0)
+    abort ();
+
+  if (!atomic_compare_exchange_strong (&v, &expected, desired))
+    abort ();
+  if (expected != 0)
+    abort ();
+  if (v != max)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/c11-stdatomic-1.c
===================================================================
--- gcc/testsuite/gcc.dg/c11-stdatomic-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/c11-stdatomic-1.c	(revision 0)
@@ -0,0 +1,119 @@ 
+/* Test stdatomic.h header contents.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <stdatomic.h>
+
+#ifndef ATOMIC_BOOL_LOCK_FREE
+# error ATOMIC_BOOL_LOCK_FREE not defined
+#endif
+
+#ifndef ATOMIC_CHAR_LOCK_FREE
+# error ATOMIC_CHAR_LOCK_FREE not defined
+#endif
+
+#ifndef ATOMIC_CHAR16_T_LOCK_FREE
+# error ATOMIC_CHAR16_T_LOCK_FREE not defined
+#endif
+
+#ifndef ATOMIC_CHAR32_T_LOCK_FREE
+# error ATOMIC_CHAR32_T_LOCK_FREE not defined
+#endif
+
+#ifndef ATOMIC_WCHAR_T_LOCK_FREE
+# error ATOMIC_WCHAR_T_LOCK_FREE not defined
+#endif
+
+#ifndef ATOMIC_SHORT_LOCK_FREE
+# error ATOMIC_SHORT_LOCK_FREE not defined
+#endif
+
+#ifndef ATOMIC_INT_LOCK_FREE
+# error ATOMIC_INT_LOCK_FREE not defined
+#endif
+
+#ifndef ATOMIC_LONG_LOCK_FREE
+# error ATOMIC_LONG_LOCK_FREE not defined
+#endif
+
+#ifndef ATOMIC_LLONG_LOCK_FREE
+# error ATOMIC_LLONG_LOCK_FREE not defined
+#endif
+
+#ifndef ATOMIC_POINTER_LOCK_FREE
+# error ATOMIC_POINTER_LOCK_FREE not defined
+#endif
+
+memory_order m0 = memory_order_relaxed;
+memory_order m1 = memory_order_consume;
+memory_order m2 = memory_order_acquire;
+memory_order m3 = memory_order_release;
+memory_order m4 = memory_order_acq_rel;
+memory_order m5 = memory_order_seq_cst;
+
+atomic_flag af = ATOMIC_FLAG_INIT;
+
+struct s { int i[100]; } sv;
+void
+f (void)
+{
+  _Atomic struct s sva = ATOMIC_VAR_INIT (sv);
+}
+
+#ifndef kill_dependency
+# error kill_dependency not defined
+#endif
+
+#define CHECK_ATOMIC_TYPEDEF(A, B)				\
+  do								\
+    {								\
+      A v;							\
+      char array1[sizeof (A) == sizeof (B) ? 1 : -1];		\
+      char array2[_Alignof (A) == _Alignof (B) ? 1 : -1];	\
+    }								\
+  while (0)
+
+#include <stddef.h>
+#include <stdint.h>
+
+void
+check_typedefs (void)
+{
+  CHECK_ATOMIC_TYPEDEF (atomic_bool, _Atomic _Bool);
+  CHECK_ATOMIC_TYPEDEF (atomic_char, _Atomic char);
+  CHECK_ATOMIC_TYPEDEF (atomic_schar, _Atomic signed char);
+  CHECK_ATOMIC_TYPEDEF (atomic_uchar, _Atomic unsigned char);
+  CHECK_ATOMIC_TYPEDEF (atomic_short, _Atomic short);
+  CHECK_ATOMIC_TYPEDEF (atomic_ushort, _Atomic unsigned short);
+  CHECK_ATOMIC_TYPEDEF (atomic_int, _Atomic int);
+  CHECK_ATOMIC_TYPEDEF (atomic_uint, _Atomic unsigned int);
+  CHECK_ATOMIC_TYPEDEF (atomic_long, _Atomic long);
+  CHECK_ATOMIC_TYPEDEF (atomic_ulong, _Atomic unsigned long);
+  CHECK_ATOMIC_TYPEDEF (atomic_llong, _Atomic long long);
+  CHECK_ATOMIC_TYPEDEF (atomic_ullong, _Atomic unsigned long long);
+  CHECK_ATOMIC_TYPEDEF (atomic_char16_t, _Atomic __CHAR16_TYPE__);
+  CHECK_ATOMIC_TYPEDEF (atomic_char32_t, _Atomic __CHAR32_TYPE__);
+  CHECK_ATOMIC_TYPEDEF (atomic_wchar_t, _Atomic wchar_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_int_least8_t, _Atomic int_least8_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_uint_least8_t, _Atomic uint_least8_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_int_least16_t, _Atomic int_least16_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_uint_least16_t, _Atomic uint_least16_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_int_least32_t, _Atomic int_least32_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_uint_least32_t, _Atomic uint_least32_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_int_least64_t, _Atomic int_least64_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_uint_least64_t, _Atomic uint_least64_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_int_fast8_t, _Atomic int_fast8_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_uint_fast8_t, _Atomic uint_fast8_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_int_fast16_t, _Atomic int_fast16_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_uint_fast16_t, _Atomic uint_fast16_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_int_fast32_t, _Atomic int_fast32_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_uint_fast32_t, _Atomic uint_fast32_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_int_fast64_t, _Atomic int_fast64_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_uint_fast64_t, _Atomic uint_fast64_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_intptr_t, _Atomic intptr_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_uintptr_t, _Atomic uintptr_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_size_t, _Atomic size_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_ptrdiff_t, _Atomic ptrdiff_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_intmax_t, _Atomic intmax_t);
+  CHECK_ATOMIC_TYPEDEF (atomic_uintmax_t, _Atomic uintmax_t);
+}
Index: gcc/ginclude/stdatomic.h
===================================================================
--- gcc/ginclude/stdatomic.h	(revision 204550)
+++ gcc/ginclude/stdatomic.h	(working copy)
@@ -26,138 +26,168 @@  see the files COPYING3 and COPYING.RUNTIME respect
 #ifndef _STDATOMIC_H
 #define _STDATOMIC_H
 
+typedef enum
+  {
+    memory_order_relaxed = __ATOMIC_RELAXED,
+    memory_order_consume = __ATOMIC_CONSUME,
+    memory_order_acquire = __ATOMIC_ACQUIRE,
+    memory_order_release = __ATOMIC_RELEASE,
+    memory_order_acq_rel = __ATOMIC_ACQ_REL,
+    memory_order_seq_cst = __ATOMIC_SEQ_CST
+  } memory_order;
 
-typedef enum memory_order
-{
-  memory_order_relaxed = __ATOMIC_RELAXED,
-  memory_order_consume = __ATOMIC_CONSUME,
-  memory_order_acquire = __ATOMIC_ACQUIRE,
-  memory_order_release = __ATOMIC_RELEASE,
-  memory_order_acq_rel = __ATOMIC_ACQ_REL,
-  memory_order_seq_cst = __ATOMIC_SEQ_CST
-} memory_order;
 
-
-typedef _Atomic _Bool 	       atomic_bool;
-typedef _Atomic char	       atomic_char;
-typedef _Atomic signed char    atomic_schar;
-typedef _Atomic unsigned char  atomic_uchar;
-typedef _Atomic short	       atomic_short;
+typedef _Atomic _Bool atomic_bool;
+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 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_TYPE__ atomic_char16_t;
 typedef _Atomic __CHAR32_TYPE__ atomic_char32_t;
-typedef _Atomic __WCHAR_TYPE__  atomic_wchar_t;
-typedef _Atomic __INT_LEAST8_TYPE__   atomic_int_least8_t;
-typedef _Atomic __UINT_LEAST8_TYPE__  atomic_uint_least8_t;
-typedef _Atomic __INT_LEAST16_TYPE__  atomic_int_least16_t;
+typedef _Atomic __WCHAR_TYPE__ atomic_wchar_t;
+typedef _Atomic __INT_LEAST8_TYPE__ atomic_int_least8_t;
+typedef _Atomic __UINT_LEAST8_TYPE__ atomic_uint_least8_t;
+typedef _Atomic __INT_LEAST16_TYPE__ atomic_int_least16_t;
 typedef _Atomic __UINT_LEAST16_TYPE__ atomic_uint_least16_t;
-typedef _Atomic __INT_LEAST32_TYPE__  atomic_int_least32_t;
+typedef _Atomic __INT_LEAST32_TYPE__ atomic_int_least32_t;
 typedef _Atomic __UINT_LEAST32_TYPE__ atomic_uint_least32_t;
-typedef _Atomic __INT_LEAST64_TYPE__  atomic_int_least64_t;
+typedef _Atomic __INT_LEAST64_TYPE__ atomic_int_least64_t;
 typedef _Atomic __UINT_LEAST64_TYPE__ atomic_uint_least64_t;
-typedef _Atomic __INT_FAST8_TYPE__    atomic_int_fast8_t;
-typedef _Atomic __UINT_FAST8_TYPE__   atomic_uint_fast8_t;
-typedef _Atomic __INT_FAST16_TYPE__   atomic_int_fast16_t;
-typedef _Atomic __UINT_FAST16_TYPE__  atomic_uint_fast16_t;
-typedef _Atomic __INT_FAST32_TYPE__   atomic_int_fast32_t;
-typedef _Atomic __UINT_FAST32_TYPE__  atomic_uint_fast32_t;
-typedef _Atomic __INT_FAST64_TYPE__   atomic_int_fast64_t;
-typedef _Atomic __UINT_FAST64_TYPE__  atomic_uint_fast64_t;
-typedef _Atomic __INTPTR_TYPE__       atomic_intptr_t;
-typedef _Atomic __UINTPTR_TYPE__      atomic_uintptr_t;
-typedef _Atomic __SIZE_TYPE__         atomic_size_t;
-typedef _Atomic __PTRDIFF_TYPE__      atomic_ptrdiff_t;
-typedef _Atomic __INTMAX_TYPE__       atomic_intmax_t;
-typedef _Atomic __UINTMAX_TYPE__      atomic_uintmax_t;        
+typedef _Atomic __INT_FAST8_TYPE__ atomic_int_fast8_t;
+typedef _Atomic __UINT_FAST8_TYPE__ atomic_uint_fast8_t;
+typedef _Atomic __INT_FAST16_TYPE__ atomic_int_fast16_t;
+typedef _Atomic __UINT_FAST16_TYPE__ atomic_uint_fast16_t;
+typedef _Atomic __INT_FAST32_TYPE__ atomic_int_fast32_t;
+typedef _Atomic __UINT_FAST32_TYPE__ atomic_uint_fast32_t;
+typedef _Atomic __INT_FAST64_TYPE__ atomic_int_fast64_t;
+typedef _Atomic __UINT_FAST64_TYPE__ atomic_uint_fast64_t;
+typedef _Atomic __INTPTR_TYPE__ atomic_intptr_t;
+typedef _Atomic __UINTPTR_TYPE__ atomic_uintptr_t;
+typedef _Atomic __SIZE_TYPE__ atomic_size_t;
+typedef _Atomic __PTRDIFF_TYPE__ atomic_ptrdiff_t;
+typedef _Atomic __INTMAX_TYPE__ atomic_intmax_t;
+typedef _Atomic __UINTMAX_TYPE__ atomic_uintmax_t;        
 
 
 #define ATOMIC_VAR_INIT(VALUE)	(VALUE)
-#define atomic_init(PTR, VAL)	{ *(PTR) = (VAL); }
+#define atomic_init(PTR, VAL)			\
+  do						\
+    {						\
+      *(PTR) = (VAL);				\
+    }						\
+  while (0)
 
-#define kill_dependency(Y)	__extension__ ({ \
-  __typeof__ (Y) __tmp = (Y); \
-  __tmp; })
+#define kill_dependency(Y)			\
+  __extension__					\
+  ({						\
+    __typeof__ (Y) __kill_dependency_tmp = (Y);	\
+    __kill_dependency_tmp;			\
+  })
 
-#define atomic_thread_fence 	__atomic_thread_fence
-#define atomic_signal_fence 	__atomic_signal_fence 
-#define atomic_is_lock_free(OBJ) __atomic_is_lock_free (sizeof (*(OBJ)), NULL)
+#define atomic_thread_fence(MO)	__atomic_thread_fence (MO)
+#define atomic_signal_fence(MO)	__atomic_signal_fence  (MO)
+#define atomic_is_lock_free(OBJ) __atomic_is_lock_free (sizeof (*(OBJ)), (OBJ))
 
+#define __atomic_type_lock_free(T)				\
+  (__atomic_always_lock_free (sizeof (T), (void *) 0)		\
+   ? 2								\
+   : (__atomic_is_lock_free (sizeof (T), (void *) 0) ? 1 : 0))
 #define ATOMIC_BOOL_LOCK_FREE			\
-			__atomic_is_lock_free (sizeof (atomic_bool), NULL)
+  __atomic_type_lock_free (atomic_bool)
 #define ATOMIC_CHAR_LOCK_FREE			\
-			__atomic_is_lock_free (sizeof (atomic_char), NULL)
+  __atomic_type_lock_free (atomic_char)
 #define ATOMIC_CHAR16_T_LOCK_FREE		\
-			__atomic_is_lock_free (sizeof (atomic_char16_t), NULL)
+  __atomic_type_lock_free (atomic_char16_t)
 #define ATOMIC_CHAR32_T_LOCK_FREE		\
-			__atomic_is_lock_free (sizeof (atomic_char32_t), NULL)
+  __atomic_type_lock_free (atomic_char32_t)
 #define ATOMIC_WCHAR_T_LOCK_FREE		\
-			__atomic_is_lock_free (sizeof (atomic_wchar_t), NULL)
+  __atomic_type_lock_free (atomic_wchar_t)
 #define ATOMIC_SHORT_LOCK_FREE 			\
-			__atomic_is_lock_free (sizeof (atomic_short), NULL)
+  __atomic_type_lock_free (atomic_short)
 #define ATOMIC_INT_LOCK_FREE 			\
-			__atomic_is_lock_free (sizeof (atomic_int), NULL)
+  __atomic_type_lock_free (atomic_int)
 #define ATOMIC_LONG_LOCK_FREE			\
-			__atomic_is_lock_free (sizeof (atomic_long), NULL)
+  __atomic_type_lock_free (atomic_long)
 #define ATOMIC_LLONG_LOCK_FREE			\
-			__atomic_is_lock_free (sizeof (atomic_llong), NULL)
+  __atomic_type_lock_free (atomic_llong)
 #define ATOMIC_POINTER_LOCK_FREE		\
-			__atomic_is_lock_free (sizeof (_Atomic void *), NULL)
+  __atomic_type_lock_free (void * _Atomic)
 
 
 /* Note that these macros require __typeof__ to remove _Atomic
    qualifiers (and const qualifiers, if those are valid on macro
    operands).
    
-   Also note that the header file uses the generic form of __atomic builtins,
-   which requires the address to be taken of the value parameter, and then
-   we pass that value on.   This allows the macros to work for any type,
-   and the compiler is smart enough to convert these to lock-free _N 
-   variants if possible, and throw away the temps.  */
+   Also note that the header file uses the generic form of __atomic
+   builtins, which requires the address to be taken of the value
+   parameter, and then we pass that value on.  This allows the macros
+   to work for any type, and the compiler is smart enough to convert
+   these to lock-free _N variants if possible, and throw away the
+   temps.  */
 
-#define atomic_store_explicit(PTR, VAL, MO) __extension__ ({	\
-  __typeof__ (*(PTR)) __tmp  = (VAL);				\
-  __atomic_store ((PTR), &__tmp, (MO)); })
+#define atomic_store_explicit(PTR, VAL, MO)		\
+  __extension__						\
+  ({							\
+    __typeof__ (*(PTR)) __atomic_store_tmp = (VAL);	\
+    __atomic_store ((PTR), &__atomic_store_tmp, (MO));	\
+  })
 
 #define atomic_store(PTR, VAL)				\
   atomic_store_explicit (PTR, VAL, __ATOMIC_SEQ_CST)
 
 
-#define atomic_load_explicit(PTR, MO) __extension__ ({	\
-  __typeof__ (*(PTR)) __tmp; 				\
-  __atomic_load ((PTR), &__tmp, __ATOMIC_SEQ_CST);	\
-  __tmp; })
+#define atomic_load_explicit(PTR, MO)					\
+  __extension__								\
+  ({									\
+    __typeof__ (*(PTR)) __atomic_load_tmp; 				\
+    __atomic_load ((PTR), &__atomic_load_tmp, (MO));			\
+    __atomic_load_tmp;							\
+  })
 
 #define atomic_load(PTR)  atomic_load_explicit (PTR, __ATOMIC_SEQ_CST)
 
 
-#define atomic_exchange_explicit(PTR, VAL, MO) __extension__ ({	\
-  __typeof__ (*(PTR)) __tmp  = (VAL);				\
-  __atomic_exchange_n ((PTR), (VAL), (MO));			\
-  __tmp; })
+#define atomic_exchange_explicit(PTR, VAL, MO)				\
+  __extension__								\
+  ({									\
+    __typeof__ (*(PTR)) __atomic_exchange_val = (VAL), __atomic_exchange_tmp; \
+    __atomic_exchange ((PTR), &__atomic_exchange_val,			\
+		       &__atomic_exchange_tmp, (MO));			\
+    __atomic_exchange_tmp;						\
+  })
 
 #define atomic_exchange(PTR, VAL) 			\
   atomic_exchange_explicit (PTR, VAL, __ATOMIC_SEQ_CST)
 
 
 #define atomic_compare_exchange_strong_explicit(PTR, VAL, DES, SUC, FAIL) \
-  __extension__ ({							\
-  __typeof__ (*(PTR)) __tmp  = (DES);					\
-  __atomic_compare_exchange_n ((PTR), (VAL), &__tmp, 0, (SUC), (FAIL)); })
+  __extension__								\
+  ({									\
+    __typeof__ (*(PTR)) __atomic_compare_exchange_tmp = (DES);		\
+    __atomic_compare_exchange ((PTR), (VAL),				\
+			       &__atomic_compare_exchange_tmp, 0,	\
+			       (SUC), (FAIL));				\
+  })
 
 #define atomic_compare_exchange_strong(PTR, VAL, DES) 			   \
   atomic_compare_exchange_strong_explicit (PTR, VAL, DES, __ATOMIC_SEQ_CST, \
 					   __ATOMIC_SEQ_CST)
 
 #define atomic_compare_exchange_weak_explicit(PTR, VAL, DES, SUC, FAIL) \
-  __extension__ ({							\
-  __typeof__ (*(PTR)) __tmp  = (DES);					\
-  __atomic_compare_exchange_n ((PTR), (VAL), &__tmp, 1, (SUC), (FAIL)); })
+  __extension__								\
+  ({									\
+    __typeof__ (*(PTR)) __atomic_compare_exchange_tmp = (DES);		\
+    __atomic_compare_exchange ((PTR), (VAL),				\
+			       &__atomic_compare_exchange_tmp, 1,	\
+			       (SUC), (FAIL));				\
+  })
 
 #define atomic_compare_exchange_weak(PTR, VAL, DES)			\
   atomic_compare_exchange_weak_explicit (PTR, VAL, DES, __ATOMIC_SEQ_CST, \
@@ -191,23 +221,24 @@  typedef _Atomic __UINT_LEAST64_TYPE__ atomic_uint_
 			  __atomic_fetch_and ((PTR), (VAL), (MO))
 
 
+typedef _Atomic struct
+{
 #if __GCC_ATOMIC_TEST_AND_SET_TRUEVAL == 1
-    typedef _Atomic bool atomic_flag;
+  _Bool __val;
 #else
-    typedef _Atomic unsigned char atomic_flag;
+  unsigned char __val;
 #endif
+} atomic_flag;
 
-#define ATOMIC_FLAG_INIT	0
+#define ATOMIC_FLAG_INIT	{ 0 }
 
 
 #define atomic_flag_test_and_set(PTR) 					\
-			__atomic_flag_test_and_set ((PTR), __ATOMIC_SEQ_CST)
+			__atomic_test_and_set ((PTR), __ATOMIC_SEQ_CST)
 #define atomic_flag_test_and_set_explicit(PTR, MO)			\
-			__atomic_flag_test_and_set ((PTR), (MO))
+			__atomic_test_and_set ((PTR), (MO))
 
-#define atomic_flag_clear(PTR)	__atomic_flag_clear ((PTR), __ATOMIC_SEQ_CST)
-#define atomic_flag_clear_explicit(PTR, MO)   __atomic_flag_clear ((PTR), (MO))
+#define atomic_flag_clear(PTR)	__atomic_clear ((PTR), __ATOMIC_SEQ_CST)
+#define atomic_flag_clear_explicit(PTR, MO)   __atomic_clear ((PTR), (MO))
 
-
-
 #endif  /* _STDATOMIC_H */