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)); } };