https://gcc.gnu.org/g:6f12a4a8d4e62d82d6f8fd79ff4dffe30f387c4d

commit r16-8535-g6f12a4a8d4e62d82d6f8fd79ff4dffe30f387c4d
Author: Marek Polacek <[email protected]>
Date:   Tue Mar 31 16:52:10 2026 -0400

    c++/reflection: spurious error with constrained return types [PR124457]
    
    Here we are emitting a bogus error in get_reflection because it
    got something for which is_auto was true: the constrained auto
    coming from make_constrained_auto.  We represent the
    return-type-requirement as a constrained auto which is in fact
    a placeholder, but in this case we don't want the error.
    
    We can move the error from get_reflection to the parser to avoid
    emitting the error.
    
            PR c++/124457
    
    gcc/cp/ChangeLog:
    
            * parser.cc (cp_parser_reflect_expression): Check is_auto here
            instead of...
            * reflect.cc (get_reflection): ...here.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/reflect/concept1.C: New test.
    
    Reviewed-by: Patrick Palka <[email protected]>

Diff:
---
 gcc/cp/parser.cc                        |  9 +++++++++
 gcc/cp/reflect.cc                       |  9 +--------
 gcc/testsuite/g++.dg/reflect/concept1.C | 14 ++++++++++++++
 3 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 62ae24f559bd..bbebc1257656 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -10155,6 +10155,15 @@ cp_parser_reflect_expression (cp_parser *parser)
         ^^B <int> is a type alias though.  */
       if (TYPE_P (t) && !type_alias_p)
        t = strip_typedefs (t);
+      /* [expr.reflect] If the type-id designates a placeholder type, R is
+        ill-formed.  This check is here rather than in get_reflection so
+        that we don't wrongly error for a return-type-requirement which is
+        represented as a constrained auto.  */
+      if (is_auto (t))
+       {
+         error_at (loc, "%<^^%> cannot be applied to a placeholder type");
+         return error_mark_node;
+       }
       return get_reflection (loc, t);
     }
   /* Try an id-expression.  */
diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc
index 3c0e029975d9..b066576eba58 100644
--- a/gcc/cp/reflect.cc
+++ b/gcc/cp/reflect.cc
@@ -123,16 +123,9 @@ get_reflection (location_t loc, tree t, reflect_kind 
kind/*=REFLECT_UNDEF*/)
 {
   STRIP_ANY_LOCATION_WRAPPER (t);
 
-  /* [expr.reflect] If the type-id designates a placeholder type, R is
-     ill-formed.  */
-  if (is_auto (t))
-    {
-      error_at (loc, "%<^^%> cannot be applied to a placeholder type");
-      return error_mark_node;
-    }
   /* Constant template parameters and pack-index-expressions cannot
      appear as operands of the reflection operator.  */
-  else if (PACK_INDEX_P (t))
+  if (PACK_INDEX_P (t))
     {
       error_at (loc, "%<^^%> cannot be applied to a pack index");
       return error_mark_node;
diff --git a/gcc/testsuite/g++.dg/reflect/concept1.C 
b/gcc/testsuite/g++.dg/reflect/concept1.C
new file mode 100644
index 000000000000..2f3d475432a2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/concept1.C
@@ -0,0 +1,14 @@
+// PR c++/124457
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+
+template <class T, auto t = ^^T>
+concept True = true;
+
+template <class T>
+concept AlsoTrue = requires (T t) {
+    { t } -> True;
+};
+void f1(True auto x);
+template <True T> void f2(T );
+auto f3(int) -> True auto;

Reply via email to