From 3fea2f61652e10c7f3abc17f0542e8bc0dd0ea25 Mon Sep 17 00:00:00 2001 From: Jake Egan Date: Sat, 14 Mar 2026 22:34:48 -0400 Subject: [PATCH] [libc++][test] Use loop with compare_exchange_weak calls (#185953) On AIX, this test sometimes fails with error `Assertion failed: y == true`. The test assumes `compare_exchange_weak` should succeed on a single call, however according to the standard: > A weak compare-and-exchange operation may fail spuriously. That is, even when the contents of memory referred to by expected and ptr are equal, it may return false and store back to expected the same memory contents that were originally there. This spurious failure enables implementation of compare-and-exchange on a broader class of machines, e.g., load-locked store-conditional machines. A consequence of spurious failure is that nearly all uses of weak compare-and-exchange will be in a loop. [atomics.ref.ops]/27 --- .../compare_exchange_weak.pass.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libcxx/test/std/atomics/atomics.ref/compare_exchange_weak.pass.cpp b/libcxx/test/std/atomics/atomics.ref/compare_exchange_weak.pass.cpp index 58cf2e0fe338..62bad17a2160 100644 --- a/libcxx/test/std/atomics/atomics.ref/compare_exchange_weak.pass.cpp +++ b/libcxx/test/std/atomics/atomics.ref/compare_exchange_weak.pass.cpp @@ -33,11 +33,11 @@ struct TestCompareExchangeWeak { std::atomic_ref const a(x); T t(T(1)); - std::same_as decltype(auto) y = a.compare_exchange_weak(t, T(2)); - assert(y == true); + while (!a.compare_exchange_weak(t, T(2))) { + } assert(a == T(2)); assert(t == T(1)); - y = a.compare_exchange_weak(t, T(3)); + std::same_as decltype(auto) y = a.compare_exchange_weak(t, T(3)); assert(y == false); assert(a == T(2)); assert(t == T(2)); @@ -49,11 +49,11 @@ struct TestCompareExchangeWeak { std::atomic_ref const a(x); T t(T(1)); - std::same_as decltype(auto) y = a.compare_exchange_weak(t, T(2), std::memory_order_seq_cst); - assert(y == true); + while (!a.compare_exchange_weak(t, T(2), std::memory_order_seq_cst)) { + } assert(a == T(2)); assert(t == T(1)); - y = a.compare_exchange_weak(t, T(3), std::memory_order_seq_cst); + std::same_as decltype(auto) y = a.compare_exchange_weak(t, T(3), std::memory_order_seq_cst); assert(y == false); assert(a == T(2)); assert(t == T(2)); @@ -65,12 +65,12 @@ struct TestCompareExchangeWeak { std::atomic_ref const a(x); T t(T(1)); - std::same_as decltype(auto) y = - a.compare_exchange_weak(t, T(2), std::memory_order_release, std::memory_order_relaxed); - assert(y == true); + while (!a.compare_exchange_weak(t, T(2), std::memory_order_release, std::memory_order_relaxed)) { + } assert(a == T(2)); assert(t == T(1)); - y = a.compare_exchange_weak(t, T(3), std::memory_order_release, std::memory_order_relaxed); + std::same_as decltype(auto) y = + a.compare_exchange_weak(t, T(3), std::memory_order_release, std::memory_order_relaxed); assert(y == false); assert(a == T(2)); assert(t == T(2));