[07/10] libstdc++: Remove reinterpret_cast uses in atomic wait/notify

Message ID 20250110212810.832494-8-jwakely@redhat.com
State New
Headers
Series C++20 atomic wait/notify ABI stabilization |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 fail Test failed
linaro-tcwg-bot/tcwg_gcc_check--master-arm fail Test failed

Commit Message

Jonathan Wakely Jan. 10, 2025, 9:23 p.m. UTC
  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(-)
  

Patch

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