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

Reply via email to