+2016-07-22 Martin Sebor <msebor@redhat.com>
+
+ PR c++/71675
+ * c-common.c (resolve_overloaded_builtin): Avoid converting
+ __atomic_compare_exchange_n return type to that of what its
+ first argument points to.
+
2016-07-22 Uros Bizjak <ubizjak@gmail.com>
* c-common.c: Use HOST_WIDE_INT_M1U instead of
return result;
if (orig_code != BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_N
&& orig_code != BUILT_IN_SYNC_LOCK_RELEASE_N
- && orig_code != BUILT_IN_ATOMIC_STORE_N)
+ && orig_code != BUILT_IN_ATOMIC_STORE_N
+ && orig_code != BUILT_IN_ATOMIC_COMPARE_EXCHANGE_N)
result = sync_resolve_return (first_param, result, orig_format);
if (fetch_op)
+2016-07-22 Martin Sebor <msebor@redhat.com>
+
+ PR c++/71675
+ * g++.dg/ext/atomic-3.C: New test.
+ * gcc.dg/atomic/pr71675.c: New test.
+
2016-07-22 Evgeny Stupachenko <evstupac@gmail.com>
* gcc.target/i386/mvc8.c: New test.
--- /dev/null
+// PR c++/71675 - __atomic_compare_exchange_n returns wrong type for typed enum
+// { dg-do compile { target c++11 } }
+
+template <class T>
+void sink (T);
+
+bool sink (bool);
+
+template <class T>
+bool test ()
+{
+ enum class E: T { };
+ static E e;
+
+ return sink (__atomic_compare_exchange_n (&e, &e, e, false, 0, 0));
+}
+
+void tests ()
+{
+ // __atomic_compare_exchange_n would fail to return bool when
+ // its arguments were one of the three character types.
+ 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>();
+}
--- /dev/null
+/* PR c++/71675 - __atomic_compare_exchange_n returns wrong type for typed enum
+ */
+/* { dg-do compile { target c11 } } */
+
+#define Test(T) \
+ do { \
+ static T x; \
+ int r [_Generic (__atomic_compare_exchange_n (&x, &x, x, 0, 0, 0), \
+ _Bool: 1, default: -1)]; \
+ (void)&r; \
+ } while (0)
+
+void f (void)
+{
+ /* __atomic_compare_exchange_n would fail to return _Bool when
+ its arguments were one of the three character types. */
+ Test (char);
+ Test (signed char);
+ Test (unsigned char);
+
+ Test (int);
+ Test (unsigned int);
+
+ Test (long);
+ Test (unsigned long);
+
+ Test (long long);
+ Test (unsigned long long);
+
+ typedef enum E { e } E;
+ Test (E);
+}