[libcxx-commits] [libcxx] [libc++][atomics] P3936R1: Safer ``atomic_ref::address`` (PR #189761)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Apr 2 03:51:27 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Hristo Hristov (H-G-Hristov)
<details>
<summary>Changes</summary>
Implements P3936R1
Closes #<!-- -->189594
# References:
- https://llvm.org/PR162236
- https://wg21.link/p3936r1
---
Full diff: https://github.com/llvm/llvm-project/pull/189761.diff
8 Files Affected:
- (modified) libcxx/docs/FeatureTestMacroTable.rst (+1-1)
- (modified) libcxx/docs/ReleaseNotes/23.rst (+1)
- (modified) libcxx/include/__atomic/atomic_ref.h (+2-1)
- (modified) libcxx/include/version (+2-2)
- (modified) libcxx/test/std/atomics/atomics.ref/address.pass.cpp (+35-4)
- (modified) libcxx/test/std/language.support/support.limits/support.limits.general/atomic.version.compile.pass.cpp (+2-2)
- (modified) libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp (+2-2)
- (modified) libcxx/utils/generate_feature_test_macro_components.py (+1-1)
``````````diff
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 0f65770a4fa14..1447261645a7b 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -420,7 +420,7 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_atomic_min_max`` *unimplemented*
---------------------------------------------------------- -----------------
- ``__cpp_lib_atomic_ref`` ``202411L``
+ ``__cpp_lib_atomic_ref`` ``202603L``
---------------------------------------------------------- -----------------
``__cpp_lib_bind_front`` ``202306L``
---------------------------------------------------------- -----------------
diff --git a/libcxx/docs/ReleaseNotes/23.rst b/libcxx/docs/ReleaseNotes/23.rst
index aeabfeedfbc5e..462c90ded8701 100644
--- a/libcxx/docs/ReleaseNotes/23.rst
+++ b/libcxx/docs/ReleaseNotes/23.rst
@@ -39,6 +39,7 @@ Implemented Papers
------------------
- P2440R1: ``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right`` (`Github <https://llvm.org/PR105184>`__)
+- P3936R1: Safer ``atomic_ref::address`` (`Github <https://llvm.org/PR189594>`__)
Improvements and New Features
-----------------------------
diff --git a/libcxx/include/__atomic/atomic_ref.h b/libcxx/include/__atomic/atomic_ref.h
index a5bc0aba38bd2..c551f99024931 100644
--- a/libcxx/include/__atomic/atomic_ref.h
+++ b/libcxx/include/__atomic/atomic_ref.h
@@ -31,6 +31,7 @@
#include <__cstddef/ptrdiff_t.h>
#include <__memory/addressof.h>
#include <__memory/is_sufficiently_aligned.h>
+#include <__type_traits/copy_cv.h>
#include <__type_traits/has_unique_object_representation.h>
#include <__type_traits/is_trivially_copyable.h>
#include <cstring>
@@ -224,7 +225,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
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp* address() const noexcept { return __ptr_; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __copy_cv_t<_Tp, void>* address() const noexcept { return __ptr_; }
# endif
protected:
diff --git a/libcxx/include/version b/libcxx/include/version
index c43d36e569efb..105a04545da0e 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -37,7 +37,7 @@ __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 202411L <atomic>
+__cpp_lib_atomic_ref 202603L <atomic>
201806L // C++20
__cpp_lib_atomic_shared_ptr 201711L <atomic>
__cpp_lib_atomic_value_initialization 201911L <atomic> <memory>
@@ -551,7 +551,7 @@ __cpp_lib_void_t 201411L <type_traits>
// # 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
+# define __cpp_lib_atomic_ref 202603L
# undef __cpp_lib_bind_front
# define __cpp_lib_bind_front 202306L
# define __cpp_lib_bitset 202306L
diff --git a/libcxx/test/std/atomics/atomics.ref/address.pass.cpp b/libcxx/test/std/atomics/atomics.ref/address.pass.cpp
index 27f0c198e89ef..ec94e639b9598 100644
--- a/libcxx/test/std/atomics/atomics.ref/address.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.ref/address.pass.cpp
@@ -8,31 +8,62 @@
// REQUIRES: std-at-least-c++26
-// constexpr T* address() const noexcept;
+// ADDITIONAL_COMPILE_FLAGS(gcc-style-warnings): -Wno-deprecated-volatile
+// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated-volatile
+
+// constexpr address-return-type address() const noexcept;
#include <atomic>
#include <cassert>
#include <concepts>
#include <memory>
+#include <type_traits>
#include "atomic_helpers.h"
#include "test_macros.h"
+template <template <class TestArg> class TestFunctor, template <class> class AddQualifier>
+struct TestEachAtomicTypeWithCV {
+ template <class T>
+ struct Qualified {
+ void operator()() const { TestFunctor<AddQualifier<T>>()(); }
+ };
+
+ void operator()() const { TestEachAtomicType<Qualified>()(); }
+};
+
+template <template <class TestArg> class TestFunctor>
+struct TestEachCVAtomicType {
+ void operator()() const {
+ TestEachAtomicTypeWithCV<TestFunctor, std::type_identity_t>()();
+ TestEachAtomicTypeWithCV<TestFunctor, std::add_const_t>()();
+ TestEachAtomicTypeWithCV<TestFunctor, std::add_volatile_t>()();
+ TestEachAtomicTypeWithCV<TestFunctor, std::add_cv_t>()();
+ }
+};
+
template <typename T>
struct TestAddress {
void operator()() const {
alignas(std::atomic_ref<T>::required_alignment) T x(T(1));
const std::atomic_ref<T> a(x);
- std::same_as<T*> decltype(auto) p = a.address();
+ using AddressReturnT =
+ std::conditional_t<std::is_const_v<T> && std::is_volatile_v<T>,
+ const volatile void,
+ std::conditional_t<std::is_volatile_v<T>,
+ volatile void,
+ std::conditional_t<std::is_const_v<T>, const void, void>>>*;
+
+ std::same_as<AddressReturnT> decltype(auto) p = a.address();
assert(std::addressof(x) == p);
- static_assert(noexcept((a.address())));
+ static_assert(noexcept(a.address()));
}
};
int main(int, char**) {
- TestEachAtomicType<TestAddress>()();
+ TestEachCVAtomicType<TestAddress>()();
return 0;
}
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 8bd027445c85b..e62416257a696 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
@@ -355,8 +355,8 @@
# ifndef __cpp_lib_atomic_ref
# error "__cpp_lib_atomic_ref should be defined in c++26"
# endif
-# if __cpp_lib_atomic_ref != 202411L
-# error "__cpp_lib_atomic_ref should have the value 202411L in c++26"
+# if __cpp_lib_atomic_ref != 202603L
+# error "__cpp_lib_atomic_ref should have the value 202603L 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 a1c8755af4ad9..71b9d573a1778 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
@@ -6341,8 +6341,8 @@
# ifndef __cpp_lib_atomic_ref
# error "__cpp_lib_atomic_ref should be defined in c++26"
# endif
-# if __cpp_lib_atomic_ref != 202411L
-# error "__cpp_lib_atomic_ref should have the value 202411L in c++26"
+# if __cpp_lib_atomic_ref != 202603L
+# error "__cpp_lib_atomic_ref should have the value 202603L 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 c5f81ca172f5a..a1d5aca1d3442 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -197,7 +197,7 @@ def add_version_header(tc):
"name": "__cpp_lib_atomic_ref",
"values": {
"c++20": 201806,
- "c++26": 202411, # P2835R7: Expose std::atomic_ref 's object address
+ "c++26": 202603,
},
"headers": ["atomic"],
},
``````````
</details>
https://github.com/llvm/llvm-project/pull/189761
More information about the libcxx-commits
mailing list