[libcxx-commits] [libcxx] f550954 - [libc++][atomics] P3936R1: Safer ``atomic_ref::address`` (#189761)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Apr 11 23:56:39 PDT 2026
Author: Hristo Hristov
Date: 2026-04-12T14:56:35+08:00
New Revision: f5509542c0660c269c202e2e7e4caeb8ed639bae
URL: https://github.com/llvm/llvm-project/commit/f5509542c0660c269c202e2e7e4caeb8ed639bae
DIFF: https://github.com/llvm/llvm-project/commit/f5509542c0660c269c202e2e7e4caeb8ed639bae.diff
LOG: [libc++][atomics] P3936R1: Safer ``atomic_ref::address`` (#189761)
Implements P3936R1
Closes #189594
# References:
- https://llvm.org/PR162236
- https://wg21.link/p3936r1
---------
Co-authored-by: A. Jiang <de34 at live.cn>
Co-authored-by: Hristo Hristov <zingam at outlook.com>
Added:
Modified:
libcxx/docs/FeatureTestMacroTable.rst
libcxx/docs/ReleaseNotes/23.rst
libcxx/docs/Status/Cxx2cPapers.csv
libcxx/include/__atomic/atomic_ref.h
libcxx/include/version
libcxx/test/std/atomics/atomics.ref/address.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/atomic.version.compile.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
libcxx/utils/generate_feature_test_macro_components.py
Removed:
################################################################################
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/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 6eda9128fda48..8e87ea68d9884 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -184,7 +184,7 @@
"`P3932R0 <https://wg21.link/P3932R0>`__","Fix LWG4470: Fix integer-from in [simd]","2026-03 (Croydon)","","","`#189591 <https://github.com/llvm/llvm-project/issues/189591>`__",""
"`P4012R1 <https://wg21.link/P4012R1>`__","Value-preserving consteval broadcast to ``simd::vec``","2026-03 (Croydon)","","","`#189592 <https://github.com/llvm/llvm-project/issues/189592>`__",""
"`P3886R0 <https://wg21.link/P3886R0>`__","Wording for AT1-057","2026-03 (Croydon)","","","`#189593 <https://github.com/llvm/llvm-project/issues/189593>`__",""
-"`P3936R1 <https://wg21.link/P3936R1>`__","Safer ``atomic_ref::address`` (FR-030-310)","2026-03 (Croydon)","","","`#189594 <https://github.com/llvm/llvm-project/issues/189594>`__",""
+"`P3936R1 <https://wg21.link/P3936R1>`__","Safer ``atomic_ref::address`` (FR-030-310)","2026-03 (Croydon)","|Complete|","23","`#189594 <https://github.com/llvm/llvm-project/issues/189594>`__",""
"`P4140R0 <https://wg21.link/P4140R0>`__","Proposed resolution for US70-126: allow incomplete types in type_order","2026-03 (Croydon)","","","`#189595 <https://github.com/llvm/llvm-project/issues/189595>`__",""
"`P3373R4 <https://wg21.link/P3373R4>`__","Of Operation States and Their Lifetimes","2026-03 (Croydon)","","","`#189597 <https://github.com/llvm/llvm-project/issues/189597>`__",""
"`P3986R1 <https://wg21.link/P3986R1>`__","A Wording Strategy for Inlinable Receivers","2026-03 (Croydon)","","","`#189598 <https://github.com/llvm/llvm-project/issues/189598>`__",""
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/ptr
diff _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..9394e8e9dd8d4 100644
--- a/libcxx/test/std/atomics/atomics.ref/address.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.ref/address.pass.cpp
@@ -8,31 +8,63 @@
// REQUIRES: std-at-least-c++26
-// constexpr T* address() const noexcept;
+// TODO: Update test after https://llvm.org/PR121414 lands.
+// 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"],
},
More information about the libcxx-commits
mailing list