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

Reply via email to