[PATCH] fix generic std::atomic<T>::compare_exchange_{weak,strong}

Nathan Froyd nfroyd@mozilla.com
Fri Jul 26 17:58:00 GMT 2013


Compiling the test program:

#include <atomic>

enum x { a, b };

std::atomic<x> v;

bool test_strong()
{
  x expected = a;
  return v.compare_exchange_strong(expected, b, std::memory_order_acq_rel);
}

bool test_weak()
{
  x expected = a;
  return v.compare_exchange_weak(expected, b, std::memory_order_acq_rel);
}

results in mysterious errors:

In file included from /home/froydnj/mini-atomic-bug.cpp:1:0:
/usr/include/c++/4.7/atomic: In function ‘bool test_strong()’:
/usr/include/c++/4.7/atomic:259:69: error: invalid failure memory model for ‘__atomic_compare_exchange’
/usr/include/c++/4.7/atomic: In function ‘bool test_weak()’:
/usr/include/c++/4.7/atomic:235:68: error: invalid failure memory model for ‘__atomic_compare_exchange’

as the generic std::atomic<T> versions of compare_exchange_strong and
compare_exchange_weak do not call __cmpexch_failure_order.

This patch corrects that oversight.  Tested on x86_64-unknown-linux-gnu.

OK to commit to trunk and active branches?

-Nathan

	* include/std/atomic (compare_exchange_weak, compare_exchange_strong):
	Add call to __cmpexch_failure_order.

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index ac2cb45..a822d0f 100644
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 813f574..2d66729 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -252,12 +252,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       bool
       compare_exchange_weak(_Tp& __e, _Tp __i,
 			    memory_order __m = memory_order_seq_cst) noexcept
-      { return compare_exchange_weak(__e, __i, __m, __m); }
+      { return compare_exchange_weak(__e, __i, __m,
+                                     __cmpexch_failure_order(__m)); }
 
       bool
       compare_exchange_weak(_Tp& __e, _Tp __i,
 		     memory_order __m = memory_order_seq_cst) volatile noexcept
-      { return compare_exchange_weak(__e, __i, __m, __m); }
+      { return compare_exchange_weak(__e, __i, __m,
+                                     __cmpexch_failure_order(__m)); }
 
       bool
       compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 
@@ -276,12 +278,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       bool
       compare_exchange_strong(_Tp& __e, _Tp __i,
 			       memory_order __m = memory_order_seq_cst) noexcept
-      { return compare_exchange_strong(__e, __i, __m, __m); }
+      { return compare_exchange_strong(__e, __i, __m,
+                                       __cmpexch_failure_order(__m)); }
 
       bool
       compare_exchange_strong(_Tp& __e, _Tp __i,
 		     memory_order __m = memory_order_seq_cst) volatile noexcept
-      { return compare_exchange_strong(__e, __i, __m, __m); }
+      { return compare_exchange_strong(__e, __i, __m,
+                                       __cmpexch_failure_order(__m)); }
     };
 
 



More information about the Gcc-patches mailing list