On Tue, 31 Mar 2026, Marek Polacek wrote:
> On Mon, Mar 30, 2026 at 06:01:16PM -0400, Patrick Palka wrote:
> > On Mon, 30 Mar 2026, Marek Polacek wrote:
> >
> > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > >
> > > -- >8 --
> > > 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.
> >
> > Could we move the auto check/diagnostic from get_reflection to only
> > the parser? IIUC the intent of [expr.reflect]/6.1 is to treat
> > ^^auto as invalid syntactically.
>
> I suppose I could, thanks. I don't love moving the check out of
> get_reflection but I guess it's safer than changing the identifier.
>
> Also fixed a missing '}' in the test.
>
> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
OK by me!
>
> -- >8 --
> 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.
> ---
> 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(-)
> create mode 100644 gcc/testsuite/g++.dg/reflect/concept1.C
>
> diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> index 8d88dc9c312..e14674607d7 100644
> --- a/gcc/cp/parser.cc
> +++ b/gcc/cp/parser.cc
> @@ -10150,6 +10150,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 405790d5f35..0b5fd64b6cd 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 00000000000..2f3d475432a
> --- /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;
>
> base-commit: 1bd1e824fc17e8adba83fd1317786aacd53457d9
> --
> 2.53.0
>
>