[libcxx-commits] [libcxx] [libc++][atomic] P2835R7: Expose `std::atomic_ref`'s object address (PR #162236)

Hristo Hristov via libcxx-commits libcxx-commits at lists.llvm.org
Tue Oct 7 21:36:56 PDT 2025


https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/162236

>From 037a1cbe1392d6fa7ec2b44605970809dd348975 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 7 Oct 2025 10:30:01 +0300
Subject: [PATCH 1/5] [libc++][atomic] P2835R7: Expose `std::atomic_ref`'s
 object address

Implements https://wg21.link/P2835R7

Closes #118377

- https://wg21.link/atomics.ref.generic.general
- https://wg21.link/atomics.ref.int
- https://wg21.link/atomics.ref.float
- https://wg21.link/atomics.ref.pointer
---
 libcxx/docs/ReleaseNotes/22.rst               |  1 +
 libcxx/docs/Status/Cxx2cPapers.csv            |  2 +-
 libcxx/include/__atomic/atomic_ref.h          |  3 ++
 .../std/atomics/atomics.ref/address.pass.cpp  | 39 +++++++++++++++++++
 4 files changed, 44 insertions(+), 1 deletion(-)
 create mode 100644 libcxx/test/std/atomics/atomics.ref/address.pass.cpp

diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst
index ec23ba9d1e3a1..1a450218cb988 100644
--- a/libcxx/docs/ReleaseNotes/22.rst
+++ b/libcxx/docs/ReleaseNotes/22.rst
@@ -43,6 +43,7 @@ Implemented Papers
 - P3044R2: sub-``string_view`` from ``string`` (`Github <https://llvm.org/PR148140>`__)
 - P3223R2: Making ``std::istream::ignore`` less surprising (`Github <https://llvm.org/PR148178>`__)
 - P3060R3: Add ``std::views::indices(n)`` (`Github <https://llvm.org/PR148175>`__)
+- P2835R7: Expose ``std::atomic_ref``'s object address (`Github <https://llvm.org/PR118377>`__)
 - P3168R2: Give ``std::optional`` Range Support (`Github <https://llvm.org/PR105430>`__)
 
 Improvements and New Features
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 69b9984f43ccf..9b83047f4b983 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -85,7 +85,7 @@
 "`P3222R0 <https://wg21.link/P3222R0>`__","Fix C++26 by adding transposed special cases for P2642 layouts","2024-11 (Wrocław)","","","`#118374 <https://github.com/llvm/llvm-project/issues/118374>`__",""
 "`P3050R2 <https://wg21.link/P3050R2>`__","Fix C++26 by optimizing ``linalg::conjugated`` for noncomplex value types","2024-11 (Wrocław)","","","`#118375 <https://github.com/llvm/llvm-project/issues/118375>`__",""
 "`P3396R1 <https://wg21.link/P3396R1>`__","``std::execution`` wording fixes","2024-11 (Wrocław)","","","`#118376 <https://github.com/llvm/llvm-project/issues/118376>`__",""
-"`P2835R7 <https://wg21.link/P2835R7>`__","Expose ``std::atomic_ref``'s object address","2024-11 (Wrocław)","","","`#118377 <https://github.com/llvm/llvm-project/issues/118377>`__",""
+"`P2835R7 <https://wg21.link/P2835R7>`__","Expose ``std::atomic_ref``'s object address","2024-11 (Wrocław)","|Complete|","22","`#118377 <https://github.com/llvm/llvm-project/issues/118377>`__",""
 "`P3323R1 <https://wg21.link/P3323R1>`__","cv-qualified types in ``atomic`` and ``atomic_ref``","2024-11 (Wrocław)","","","`#118378 <https://github.com/llvm/llvm-project/issues/118378>`__",""
 "`P3508R0 <https://wg21.link/P3508R0>`__","Wording for ""constexpr for specialized memory algorithms""","2024-11 (Wrocław)","","","`#118379 <https://github.com/llvm/llvm-project/issues/118379>`__",""
 "`P3369R0 <https://wg21.link/P3369R0>`__","constexpr for ``uninitialized_default_construct``","2024-11 (Wrocław)","","","`#118380 <https://github.com/llvm/llvm-project/issues/118380>`__",""
diff --git a/libcxx/include/__atomic/atomic_ref.h b/libcxx/include/__atomic/atomic_ref.h
index 9bdc6b1160d2c..1b5191ebb31cc 100644
--- a/libcxx/include/__atomic/atomic_ref.h
+++ b/libcxx/include/__atomic/atomic_ref.h
@@ -220,6 +220,9 @@ struct __atomic_ref_base {
   }
   _LIBCPP_HIDE_FROM_ABI void notify_one() const noexcept { std::__atomic_notify_one(*this); }
   _LIBCPP_HIDE_FROM_ABI void notify_all() const noexcept { std::__atomic_notify_all(*this); }
+#  if _LIBCPP_STD_VER >= 26
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp* address() const noexcept { return __ptr_; }
+#  endif
 
 protected:
   using _Aligned_Tp [[__gnu__::__aligned__(required_alignment), __gnu__::__nodebug__]] = _Tp;
diff --git a/libcxx/test/std/atomics/atomics.ref/address.pass.cpp b/libcxx/test/std/atomics/atomics.ref/address.pass.cpp
new file mode 100644
index 0000000000000..5b00e13234dbf
--- /dev/null
+++ b/libcxx/test/std/atomics/atomics.ref/address.pass.cpp
@@ -0,0 +1,39 @@
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// XFAIL: !has-64-bit-atomics
+// XFAIL: !has-1024-bit-atomics
+
+// constexpr T* address() const noexcept;
+
+#include <atomic>
+#include <cassert>
+#include <concepts>
+
+#include "atomic_helpers.h"
+#include "test_macros.h"
+
+template <typename T>
+struct TestAddress {
+  void operator()() const {
+    T x(T(1));
+    const std::atomic_ref<T> a(x);
+
+    std::same_as<T*> decltype(auto) p = a.address();
+    assert(std::addressof(x) == p);
+
+    static_assert(noexcept((a.address())));
+  }
+};
+
+int main(int, char**) {
+  TestEachAtomicType<TestAddress>()();
+
+  return 0;
+}

>From 8b61107727d62c7dc2cbe8d1cb49326b7985605c Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 7 Oct 2025 17:50:37 +0300
Subject: [PATCH 2/5] Addressed review comments

---
 libcxx/include/__atomic/atomic_ref.h          |  2 +-
 .../diagnostics/atomic.nodiscard.verify.cpp   | 37 +++++++++++++++++++
 .../std/atomics/atomics.ref/address.pass.cpp  |  1 +
 3 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 libcxx/test/libcxx/diagnostics/atomic.nodiscard.verify.cpp

diff --git a/libcxx/include/__atomic/atomic_ref.h b/libcxx/include/__atomic/atomic_ref.h
index 1b5191ebb31cc..ec5ae2c28c310 100644
--- a/libcxx/include/__atomic/atomic_ref.h
+++ b/libcxx/include/__atomic/atomic_ref.h
@@ -221,7 +221,7 @@ struct __atomic_ref_base {
   _LIBCPP_HIDE_FROM_ABI void notify_one() const noexcept { std::__atomic_notify_one(*this); }
   _LIBCPP_HIDE_FROM_ABI void notify_all() const noexcept { std::__atomic_notify_all(*this); }
 #  if _LIBCPP_STD_VER >= 26
-  _LIBCPP_HIDE_FROM_ABI constexpr _Tp* address() const noexcept { return __ptr_; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp* address() const noexcept { return __ptr_; }
 #  endif
 
 protected:
diff --git a/libcxx/test/libcxx/diagnostics/atomic.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/atomic.nodiscard.verify.cpp
new file mode 100644
index 0000000000000..c1e8aeb97eb8a
--- /dev/null
+++ b/libcxx/test/libcxx/diagnostics/atomic.nodiscard.verify.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// check that <atomic> functions are marked [[nodiscard]]
+
+// clang-format off
+
+#include <atomic>
+
+#include "atomic_helpers.h"
+#include "test_macros.h"
+
+template <typename T>
+struct TestAtomicRef {
+  void operator()() const {
+    T x(T(1));
+    const std::atomic_ref<T> a(x);
+
+#if TEST_STD_VER >= 26
+  a.address(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+  }
+};
+
+void test() {
+  TestAtomicRef<UserAtomicType>()();
+  TestAtomicRef<int>()();
+  TestAtomicRef<float>()();
+  TestAtomicRef<char*>()();
+}
diff --git a/libcxx/test/std/atomics/atomics.ref/address.pass.cpp b/libcxx/test/std/atomics/atomics.ref/address.pass.cpp
index 5b00e13234dbf..23c6088f474eb 100644
--- a/libcxx/test/std/atomics/atomics.ref/address.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.ref/address.pass.cpp
@@ -15,6 +15,7 @@
 #include <atomic>
 #include <cassert>
 #include <concepts>
+#include <memory>
 
 #include "atomic_helpers.h"
 #include "test_macros.h"

>From cb00fb160a299bc5d233aa8128ee3aa61599c508 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 7 Oct 2025 18:18:56 +0300
Subject: [PATCH 3/5] Upped version value

---
 libcxx/docs/FeatureTestMacroTable.rst                        | 2 ++
 libcxx/include/version                                       | 5 ++++-
 .../support.limits.general/atomic.version.compile.pass.cpp   | 4 ++--
 .../support.limits.general/version.version.compile.pass.cpp  | 4 ++--
 libcxx/utils/generate_feature_test_macro_components.py       | 5 ++++-
 5 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index c7f01e6868395..8fba6db871f08 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -418,6 +418,8 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_atomic_min_max``                               *unimplemented*
     ---------------------------------------------------------- -----------------
+    ``__cpp_lib_atomic_ref``                                   ``202411L``
+    ---------------------------------------------------------- -----------------
     ``__cpp_lib_bind_front``                                   ``202306L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_bitset``                                       ``202306L``
diff --git a/libcxx/include/version b/libcxx/include/version
index 99e69299921fa..a936def8d81c2 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -37,7 +37,8 @@ __cpp_lib_atomic_float                                  201711L <atomic>
 __cpp_lib_atomic_is_always_lock_free                    201603L <atomic>
 __cpp_lib_atomic_lock_free_type_aliases                 201907L <atomic>
 __cpp_lib_atomic_min_max                                202403L <atomic>
-__cpp_lib_atomic_ref                                    201806L <atomic>
+__cpp_lib_atomic_ref                                    202411L <atomic>
+                                                        201806L // C++20
 __cpp_lib_atomic_shared_ptr                             201711L <atomic>
 __cpp_lib_atomic_value_initialization                   201911L <atomic> <memory>
 __cpp_lib_atomic_wait                                   201907L <atomic>
@@ -546,6 +547,8 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_aligned_accessor                     202411L
 // # define __cpp_lib_associative_heterogeneous_insertion  202306L
 // # define __cpp_lib_atomic_min_max                       202403L
+# undef  __cpp_lib_atomic_ref
+# define __cpp_lib_atomic_ref                           202411L
 # undef  __cpp_lib_bind_front
 # define __cpp_lib_bind_front                           202306L
 # define __cpp_lib_bitset                               202306L
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/atomic.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/atomic.version.compile.pass.cpp
index 3470e2b28bc40..d6c38bd4915c8 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/atomic.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/atomic.version.compile.pass.cpp
@@ -367,8 +367,8 @@
 #  ifndef __cpp_lib_atomic_ref
 #    error "__cpp_lib_atomic_ref should be defined in c++26"
 #  endif
-#  if __cpp_lib_atomic_ref != 201806L
-#    error "__cpp_lib_atomic_ref should have the value 201806L in c++26"
+#  if __cpp_lib_atomic_ref != 202411L
+#    error "__cpp_lib_atomic_ref should have the value 202411L in c++26"
 #  endif
 
 #  if !defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index 9a8a1da88ee8f..af3e605bfbb15 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -6337,8 +6337,8 @@
 #  ifndef __cpp_lib_atomic_ref
 #    error "__cpp_lib_atomic_ref should be defined in c++26"
 #  endif
-#  if __cpp_lib_atomic_ref != 201806L
-#    error "__cpp_lib_atomic_ref should have the value 201806L in c++26"
+#  if __cpp_lib_atomic_ref != 202411L
+#    error "__cpp_lib_atomic_ref should have the value 202411L in c++26"
 #  endif
 
 #  if !defined(_LIBCPP_VERSION)
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 2d5b66d994da0..c8b82e84eb003 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -195,7 +195,10 @@ def add_version_header(tc):
         },
         {
             "name": "__cpp_lib_atomic_ref",
-            "values": {"c++20": 201806},
+            "values": {
+                "c++20": 201806,
+                "c++26": 202411,  # P2835R7: Expose std::atomic_ref 's object address
+            },
             "headers": ["atomic"],
         },
         {

>From 0334bfddc55a0d0c0f7c9459328c28b148ef8cef Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 7 Oct 2025 20:22:53 +0300
Subject: [PATCH 4/5] Fix CI

---
 .../test/libcxx/diagnostics/atomic.nodiscard.verify.cpp   | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/libcxx/test/libcxx/diagnostics/atomic.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/atomic.nodiscard.verify.cpp
index c1e8aeb97eb8a..85e5f0b44d2d0 100644
--- a/libcxx/test/libcxx/diagnostics/atomic.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/atomic.nodiscard.verify.cpp
@@ -6,12 +6,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-// UNSUPPORTED: c++03
+// REQUIRES: std-at-least-c++26
 
 // check that <atomic> functions are marked [[nodiscard]]
 
-// clang-format off
-
 #include <atomic>
 
 #include "atomic_helpers.h"
@@ -23,9 +21,7 @@ struct TestAtomicRef {
     T x(T(1));
     const std::atomic_ref<T> a(x);
 
-#if TEST_STD_VER >= 26
-  a.address(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}}
-#endif
+    a.address(); // expected-warning 4 {{ignoring return value of function declared with 'nodiscard' attribute}}
   }
 };
 

>From 2c62e4c51e9f866d20f0d8765f7499ab94679545 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 8 Oct 2025 07:36:37 +0300
Subject: [PATCH 5/5] Try to fix clang-cl CI

---
 libcxx/test/std/atomics/atomics.ref/address.pass.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libcxx/test/std/atomics/atomics.ref/address.pass.cpp b/libcxx/test/std/atomics/atomics.ref/address.pass.cpp
index 23c6088f474eb..8856c5ea9ffbb 100644
--- a/libcxx/test/std/atomics/atomics.ref/address.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.ref/address.pass.cpp
@@ -8,7 +8,6 @@
 // REQUIRES: std-at-least-c++26
 
 // XFAIL: !has-64-bit-atomics
-// XFAIL: !has-1024-bit-atomics
 
 // constexpr T* address() const noexcept;
 



More information about the libcxx-commits mailing list