https://gcc.gnu.org/g:5729a28e994e28df73088bcd87042fd9383085a5
commit r16-992-g5729a28e994e28df73088bcd87042fd9383085a5 Author: Jonathan Wakely <jwak...@redhat.com> Date: Sat Jan 18 21:10:41 2025 +0000 libstdc++: Remove reinterpret_cast uses in atomic wait/notify We can pass around void* instead of casting incompatible pointers to __platform_wait_t*, and then only static_cast to __platform_wait_t* when we know that's valid. libstdc++-v3/ChangeLog: * include/bits/atomic_timed_wait.h (__wait_until_impl): Change first parameter to const void* and then static_cast to const __platform_wait_t* when not using proxied wait. (__wait_until): Change first parameter to const void*. (__wait_for): Likewise. (__atomic_wait_address_until): Remove reinterpret_cast and allow address to implicitly convert to const void* instead. (__atomic_wait_address_for): Likewise. * include/bits/atomic_wait.h: (__wait_impl, __notify_impl): Change first parameter to const void* and then static_cast to const __platform_wait_t* when not using proxied wait. (__atomic_wait_address, __atomic_notify_address) Remove reinterpret_cast and allow address to implicitly convert to const void* instead. Diff: --- libstdc++-v3/include/bits/atomic_timed_wait.h | 17 ++++++----------- libstdc++-v3/include/bits/atomic_wait.h | 16 ++++++---------- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/libstdc++-v3/include/bits/atomic_timed_wait.h b/libstdc++-v3/include/bits/atomic_timed_wait.h index a916c10879b7..cbf9187f2bb8 100644 --- a/libstdc++-v3/include/bits/atomic_timed_wait.h +++ b/libstdc++-v3/include/bits/atomic_timed_wait.h @@ -170,8 +170,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } inline __wait_result_type - __wait_until_impl(const __platform_wait_t* __addr, - const __wait_args_base& __a, + __wait_until_impl(const void* __addr, const __wait_args_base& __a, const __wait_clock_t::time_point& __atime) { __wait_args_base __args = __a; @@ -184,7 +183,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __atomic_load(__wait_addr, &__args._M_old, __args._M_order); } else - __wait_addr = __addr; + __wait_addr = static_cast<const __platform_wait_t*>(__addr); if (__args & __wait_flags::__do_spin) { @@ -222,7 +221,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Returns {true, val} if wait ended before a timeout. template<typename _Clock, typename _Dur> __wait_result_type - __wait_until(const __platform_wait_t* __addr, const __wait_args_base& __args, + __wait_until(const void* __addr, const __wait_args_base& __args, const chrono::time_point<_Clock, _Dur>& __atime) noexcept { auto __at = __detail::__to_wait_clock(__atime); @@ -243,7 +242,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Returns {true, val} if wait ended before a timeout. template<typename _Rep, typename _Period> __wait_result_type - __wait_for(const __platform_wait_t* __addr, const __wait_args_base& __args, + __wait_for(const void* __addr, const __wait_args_base& __args, const chrono::duration<_Rep, _Period>& __rtime) noexcept { if (!__rtime.count()) @@ -270,13 +269,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const chrono::time_point<_Clock, _Dur>& __atime, bool __bare_wait = false) noexcept { - const auto __wait_addr = - reinterpret_cast<const __detail::__platform_wait_t*>(__addr); __detail::__wait_args __args{ __addr, __bare_wait }; _Tp __val = __vfn(); while (!__pred(__val)) { - auto __res = __detail::__wait_until(__wait_addr, __args, __atime); + auto __res = __detail::__wait_until(__addr, __args, __atime); if (!__res.first) // timed out return __res.first; // C++26 will also return last observed __val @@ -320,13 +317,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const chrono::duration<_Rep, _Period>& __rtime, bool __bare_wait = false) noexcept { - const auto __wait_addr = - reinterpret_cast<const __detail::__platform_wait_t*>(__addr); __detail::__wait_args __args{ __addr, __bare_wait }; _Tp __val = __vfn(); while (!__pred(__val)) { - auto __res = __detail::__wait_for(__wait_addr, __args, __rtime); + auto __res = __detail::__wait_for(__addr, __args, __rtime); if (!__res.first) // timed out return __res.first; // C++26 will also return last observed __val diff --git a/libstdc++-v3/include/bits/atomic_wait.h b/libstdc++-v3/include/bits/atomic_wait.h index 5fd00c22565b..cfda323a3ab6 100644 --- a/libstdc++-v3/include/bits/atomic_wait.h +++ b/libstdc++-v3/include/bits/atomic_wait.h @@ -355,7 +355,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } inline __wait_result_type - __wait_impl(const __platform_wait_t* __addr, const __wait_args_base& __a) + __wait_impl(const void* __addr, const __wait_args_base& __a) { __wait_args_base __args = __a; __waiter_pool_impl* __pool = nullptr; @@ -368,7 +368,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __atomic_load(__wait_addr, &__args._M_old, __args._M_order); } else - __wait_addr = __addr; + __wait_addr = static_cast<const __platform_wait_t*>(__addr); if (__args & __wait_flags::__do_spin) { @@ -401,7 +401,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } inline void - __notify_impl(const __platform_wait_t* __addr, [[maybe_unused]] bool __all, + __notify_impl(const void* __addr, [[maybe_unused]] bool __all, const __wait_args_base& __args) { __waiter_pool_impl* __pool = nullptr; @@ -420,7 +420,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __all = true; } else // Use the atomic variable's own address. - __wait_addr = __addr; + __wait_addr = static_cast<const __platform_wait_t*>(__addr); if (__args & __wait_flags::__track_contention) { @@ -449,8 +449,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __atomic_wait_address(const _Tp* __addr, _Pred&& __pred, _ValFn&& __vfn, bool __bare_wait = false) noexcept { - const auto __wait_addr = - reinterpret_cast<const __detail::__platform_wait_t*>(__addr); __detail::__wait_args __args{ __addr, __bare_wait }; _Tp __val = __vfn(); while (!__pred(__val)) @@ -462,7 +460,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __val); // Otherwise, it's a proxy wait and the proxy's _M_ver is used. - __detail::__wait_impl(__wait_addr, __args); + __detail::__wait_impl(__addr, __args); __val = __vfn(); } // C++26 will return __val @@ -494,10 +492,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __atomic_notify_address(const _Tp* __addr, bool __all, bool __bare_wait = false) noexcept { - const auto __wait_addr = - reinterpret_cast<const __detail::__platform_wait_t*>(__addr); __detail::__wait_args __args{ __addr, __bare_wait }; - __detail::__notify_impl(__wait_addr, __all, __args); + __detail::__notify_impl(__addr, __all, __args); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std