[gcc r17-2853] libstdc++: Reject user-defined specializations for coroutine_handle.

Tomasz Kaminski via Gcc-cvs <[email protected]> Fri, 31 Jul 2026 15:34:57 +0000 (GMT)
Newsgroups gmane.comp.gcc.cvs
Message-ID <20260731153457.B91874BA5435__1475.82884398929$1785512107$gmane$org@sourceware.org>
https://gcc.gnu.org/g:b90df55625eb40b05e0628097765d0a2cb368ced

commit r17-2853-gb90df55625eb40b05e0628097765d0a2cb368ced
Author: Tomasz KamiƄski <[email protected]>
Date:   Fri Jul 31 16:52:09 2026 +0200

    libstdc++: Reject user-defined specializations for coroutine_handle.
    
    The P0912R5, "Merge Coroutines TS into C++20 working draft" that
    introduced them already included made specializing coroutine_handle
    ill-formed, no diagnostic required.
    
    This is QoI improvment, that produces diagnostic in such situation
    by decaroting base template with [[_Clang::__no_specializations]].
    
    libstdc++-v3/ChangeLog:
    
            * include/std/coroutine: Ignore -Winvalid-specialization in file.
            (std::coroutine_handle): Add clang::no_specializations attribute.
            * testsuite/18_support/coroutines/specializations_neg.cc: New test.

Diff:
---
 libstdc++-v3/include/std/coroutine                     |  3 ++-
 .../18_support/coroutines/specializations_neg.cc       | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/coroutine b/libstdc++-v3/include/std/coroutine
index 7f7295d0fa57..61ca185a1a47 100644
--- a/libstdc++-v3/include/std/coroutine
+++ b/libstdc++-v3/include/std/coroutine
@@ -35,6 +35,7 @@
 
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wc++17-extensions"
+#pragma GCC diagnostic ignored "-Winvalid-specialization"
 
 #define __glibcxx_want_coroutine
 #include <bits/version.h>
@@ -195,7 +196,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   template <typename _Promise>
-    struct coroutine_handle
+    struct _GLIBCXX_NO_SPECIALIZATIONS coroutine_handle
     {
       // [coroutine.handle.con], construct/reset
 
diff --git a/libstdc++-v3/testsuite/18_support/coroutines/specializations_neg.cc b/libstdc++-v3/testsuite/18_support/coroutines/specializations_neg.cc
new file mode 100644
index 000000000000..0e7aabc6b0ba
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/coroutines/specializations_neg.cc
@@ -0,0 +1,18 @@
+// { dg-do compile { target c++20 } }
+
+#include <coroutine>
+
+struct Promise
+{};
+
+template<>
+struct std::coroutine_handle<Promise> // { dg-error "cannot be specialized" }
+{};
+
+template<typename>
+struct PromiseTempl
+{};
+
+template<typename T>
+struct std::coroutine_handle<PromiseTempl<T>> // { dg-error "cannot be specialized" }
+{};