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?
-- >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