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;
