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(-)
@@ -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
@@ -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