https://gcc.gnu.org/g:27c985b774b2ccb0d2aa9eb72acf05f98b790296

commit r15-3615-g27c985b774b2ccb0d2aa9eb72acf05f98b790296
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Wed Sep 11 10:17:23 2024 +0100

    libstdc++: Simplify std::launder definition
    
    A single static assert is a much simpler way to implement the
    compile-time preconditions on std::launder than an overload set of
    deleted functions and function templates. The only difficulty is that
    <new> doesn't include <type_traits> so we can't use std::is_function and
    std::is_void for the checks. That can be worked around though, by using
    the __is_same and __is_function built-ins. If the __is_function built-in
    isn't supported then the __builtin_launder built-in will give an error
    anyway, since the commit preceding this one.
    
    We can also remove the redundant __cplusplus >= 201703L check around the
    definitions of std::launder and the interference constants, which are
    already guarded by the appropriate feature test macros.
    
    libstdc++-v3/ChangeLog:
    
            * libsupc++/new (launder): Add static_assert and remove deleted
            overloads.
            * testsuite/18_support/launder/requirements_neg.cc: Adjust
            expected diagnostics.

Diff:
---
 libstdc++-v3/libsupc++/new                         | 36 +++++++++-------------
 .../18_support/launder/requirements_neg.cc         | 15 +++++----
 2 files changed, 24 insertions(+), 27 deletions(-)

diff --git a/libstdc++-v3/libsupc++/new b/libstdc++-v3/libsupc++/new
index 2e2038e1a82c..af5c7690bb99 100644
--- a/libstdc++-v3/libsupc++/new
+++ b/libstdc++-v3/libsupc++/new
@@ -198,7 +198,6 @@ inline void operator delete[](void*, void*) 
_GLIBCXX_USE_NOEXCEPT { }
 //@}
 } // extern "C++"
 
-#if __cplusplus >= 201703L
 namespace std
 {
 #ifdef __cpp_lib_launder // C++ >= 17 && HAVE_BUILTIN_LAUNDER
@@ -206,33 +205,28 @@ namespace std
   template<typename _Tp>
     [[nodiscard]] constexpr _Tp*
     launder(_Tp* __p) noexcept
-    { return __builtin_launder(__p); }
-
-  // The program is ill-formed if T is a function type or
-  // (possibly cv-qualified) void.
-
-  template<typename _Ret, typename... _Args _GLIBCXX_NOEXCEPT_PARM>
-    void launder(_Ret (*)(_Args...) _GLIBCXX_NOEXCEPT_QUAL) = delete;
-  template<typename _Ret, typename... _Args _GLIBCXX_NOEXCEPT_PARM>
-    void launder(_Ret (*)(_Args......) _GLIBCXX_NOEXCEPT_QUAL) = delete;
-
-  void launder(void*) = delete;
-  void launder(const void*) = delete;
-  void launder(volatile void*) = delete;
-  void launder(const volatile void*) = delete;
+    {
+      if constexpr (__is_same(const volatile _Tp, const volatile void))
+       static_assert(!__is_same(const volatile _Tp, const volatile void),
+                     "std::launder argument must not be a void pointer");
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_function)
+      else if constexpr (__is_function(_Tp))
+       static_assert(!__is_function(_Tp),
+                     "std::launder argument must not be a function pointer");
+#endif
+      else
+       return __builtin_launder(__p);
+      return nullptr;
+    }
 #endif // __cpp_lib_launder
 
 #ifdef __cpp_lib_hardware_interference_size // C++ >= 17 && 
defined(gcc_dest_sz)
   inline constexpr size_t hardware_destructive_interference_size = 
__GCC_DESTRUCTIVE_SIZE;
   inline constexpr size_t hardware_constructive_interference_size = 
__GCC_CONSTRUCTIVE_SIZE;
 #endif // __cpp_lib_hardware_interference_size
-}
-#endif // C++17
 
 // Emitted despite the FTM potentially being undefined.
-#if __cplusplus > 201703L
-namespace std
-{
+#if __cplusplus >= 202002L
   /// Tag type used to declare a class-specific operator delete that can
   /// invoke the destructor before deallocating the memory.
   struct destroying_delete_t
@@ -241,8 +235,8 @@ namespace std
   };
   /// Tag variable of type destroying_delete_t.
   inline constexpr destroying_delete_t destroying_delete{};
-}
 #endif // C++20
+}
 
 #pragma GCC visibility pop
 
diff --git a/libstdc++-v3/testsuite/18_support/launder/requirements_neg.cc 
b/libstdc++-v3/testsuite/18_support/launder/requirements_neg.cc
index 2808ebf614dd..82ce0b35a8c6 100644
--- a/libstdc++-v3/testsuite/18_support/launder/requirements_neg.cc
+++ b/libstdc++-v3/testsuite/18_support/launder/requirements_neg.cc
@@ -25,14 +25,17 @@ int f2(const char*, ...);
 void
 test01()
 {
-  std::launder( &f1 ); // { dg-error "deleted function" }
-  std::launder( &f2 ); // { dg-error "deleted function" }
+  std::launder( &f1 ); // { dg-error "here" }
+  std::launder( &f2 ); // { dg-error "here" }
   void* p = nullptr;
-  std::launder( p );  // { dg-error "deleted function" }
+  std::launder( p );   // { dg-error "here" }
   const void* cp = nullptr;
-  std::launder( cp );  // { dg-error "deleted function" }
+  std::launder( cp );  // { dg-error "here" }
   volatile void* vp = nullptr;
-  std::launder( vp );  // { dg-error "deleted function" }
+  std::launder( vp );  // { dg-error "here" }
   const volatile void* cvp = nullptr;
-  std::launder( cvp );  // { dg-error "deleted function" }
+  std::launder( cvp ); // { dg-error "here" }
 }
+// { dg-error "std::launder argument must not be a void pointer" "" { target 
*-*-* } 0 }
+// { dg-error "std::launder argument must not be a function pointer" "" { 
target *-*-* } 0 }
+// { dg-warning "ignoring return value" "nodiscard" { target *-*-* } 0 }

Reply via email to