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.
---
 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
-- 
2.49.0

Reply via email to