From 6e81ed68c59e4af13bbe53fbf666435204f9df58 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 16 Jun 2024 07:10:11 -0700 Subject: [PATCH 1/3] Fix GH 4728. For `!_ATOMIC_HAS_DCAS`: If we're `is_always_lock_free` (power of two, at most 1 pointer), return true. Otherwise, we have to be `_Is_potentially_lock_free` (power of two, at most 2 pointers) and have cmpxchg16b. --- stl/inc/atomic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/atomic b/stl/inc/atomic index 5f7e7300499..d093032d371 100644 --- a/stl/inc/atomic +++ b/stl/inc/atomic @@ -2371,7 +2371,7 @@ public: if constexpr (is_always_lock_free) { return true; } else { - return __std_atomic_has_cmpxchg16b() != 0; + return _Is_potentially_lock_free && __std_atomic_has_cmpxchg16b() != 0; } #endif // ^^^ !_ATOMIC_HAS_DCAS ^^^ } From 5e03fc6bf728b2ccad3f38faa6335647a53f95c8 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 16 Jun 2024 08:39:24 -0700 Subject: [PATCH 2/3] Test GH 4728. --- tests/std/tests/P0019R8_atomic_ref/test.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/std/tests/P0019R8_atomic_ref/test.cpp b/tests/std/tests/P0019R8_atomic_ref/test.cpp index 61c25f68eb3..6cdfd4518ad 100644 --- a/tests/std/tests/P0019R8_atomic_ref/test.cpp +++ b/tests/std/tests/P0019R8_atomic_ref/test.cpp @@ -447,6 +447,22 @@ void test_gh_4472() { assert(ar.is_lock_free()); } +// GH-4728 ": On x64, atomic_ref::is_lock_free() incorrectly returns true when it shouldn't" +void test_gh_4728() { + struct Large { + char str[100]{}; + }; + + alignas(std::atomic_ref::required_alignment) Large lg{}; + + static_assert(std::atomic_ref::required_alignment == alignof(Large)); + + static_assert(!std::atomic_ref::is_always_lock_free); + + std::atomic_ref ar{lg}; + assert(!ar.is_lock_free()); +} + int main() { test_ops(); test_ops(); @@ -500,6 +516,7 @@ int main() { test_gh_1497(); test_gh_4472(); + test_gh_4728(); } #endif // ^^^ run test ^^^ From a76faa5f917c9c95329d828bb58bfb09661e9a69 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 17 Jun 2024 07:23:13 -0700 Subject: [PATCH 3/3] Use `if constexpr (_Is_potentially_lock_free)`. Co-authored-by: Alex Guteniev --- stl/inc/atomic | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stl/inc/atomic b/stl/inc/atomic index d093032d371..307168b01e2 100644 --- a/stl/inc/atomic +++ b/stl/inc/atomic @@ -2370,8 +2370,10 @@ public: #else // ^^^ _ATOMIC_HAS_DCAS / !_ATOMIC_HAS_DCAS vvv if constexpr (is_always_lock_free) { return true; + } else if constexpr (_Is_potentially_lock_free) { + return __std_atomic_has_cmpxchg16b() != 0; } else { - return _Is_potentially_lock_free && __std_atomic_has_cmpxchg16b() != 0; + return false; } #endif // ^^^ !_ATOMIC_HAS_DCAS ^^^ }