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 (__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. --- libstdc++-v3/include/bits/atomic_timed_wait.h | 8 ++------ libstdc++-v3/include/bits/atomic_wait.h | 16 ++++++---------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/libstdc++-v3/include/bits/atomic_timed_wait.h b/libstdc++-v3/include/bits/atomic_timed_wait.h index 7e2017f2f515..645b8cfc4a8b 100644 --- a/libstdc++-v3/include/bits/atomic_timed_wait.h +++ b/libstdc++-v3/include/bits/atomic_timed_wait.h @@ -271,13 +271,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 @@ -321,13 +319,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 38a2bd3f95f2..db4fa031d2cf 100644 --- a/libstdc++-v3/include/bits/atomic_wait.h +++ b/libstdc++-v3/include/bits/atomic_wait.h @@ -340,7 +340,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } inline __wait_result_type - __wait_impl(const __platform_wait_t* __addr, const __wait_args* __a) + __wait_impl(const void* __addr, const __wait_args* __a) { __wait_args __args{ *__a }; __waiter_pool_impl* __pool = nullptr; @@ -353,7 +353,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) { @@ -386,7 +386,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* __a) { __wait_args __args{ *__a }; @@ -407,7 +407,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) { @@ -435,8 +435,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)) @@ -448,7 +446,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 @@ -480,10 +478,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 -- 2.47.1