On Fri, Oct 3, 2025 at 1:22 PM Patrick Palka <[email protected]> wrote:
>
> Hey Egas,
>
> On Fri, 3 Oct 2025, Egas Ribeiro wrote:
>
> > When parsing function parameters containing a struct declaration,
> > initially auto_is_implicit_function_template_parm_p is set to true by
> > cp_parser_parameter_declaration_clause. However, later when we enter
> > class scope and scope_kind becomes sk_class, we don't set it to false, so
> > cp_parser_simple_type_specifier will call
> > synthesize_implicit_template_parm, which expects that
> > current_binding_level->kind == sk_function_parms, triggering a failed
> > assertion. This fix ensures that auto_is_implicit_function_template_parm_p
> > isn't set when parsing a struct body definition.
> >
> > gcc/cp/ChangeLog:
> >
> > PR c++/122112
> > * parser.cc (cp_parser_parameter_declaration_clause): Don't
> > enable auto_is_implicit_function_template_parm_p when entering
> > class scope.
> >
> > gcc/testsuite/ChangeLog:
> >
> > PR c++/122112
> > * g++.dg/parse/auto-struct-param.C: New test.
> >
> > Signed-off-by: Egas Ribeiro <[email protected]>
>
> Thanks for the patch! I assume you bootstrapped+regtested it on
> x86_64-linux and there were no regressions? If so then it looks good to
> me, nice job. Jason, what do you think?
Just saw in your other mail that this was regtested on x86_64-linux, great.
>
> > ---
> > gcc/cp/parser.cc | 8 +++++++-
> > gcc/testsuite/g++.dg/parse/auto-struct-param.C | 4 ++++
> > 2 files changed, 11 insertions(+), 1 deletion(-)
> > create mode 100644 gcc/testsuite/g++.dg/parse/auto-struct-param.C
> >
> > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> > index 8d1187f8cda..ccf5783de7f 100644
> > --- a/gcc/cp/parser.cc
> > +++ b/gcc/cp/parser.cc
> > @@ -28124,6 +28124,7 @@ cp_parser_class_specifier (cp_parser* parser)
> > bool in_switch_statement_p;
> > bool saved_in_unbraced_linkage_specification_p;
> > bool saved_in_unbraced_export_declaration_p;
> > + bool saved_auto_is_implicit_function_template_parm_p;
> > tree old_scope = NULL_TREE;
> > tree scope = NULL_TREE;
> > cp_token *closing_brace;
> > @@ -28181,6 +28182,10 @@ cp_parser_class_specifier (cp_parser* parser)
> > saved_in_unbraced_export_declaration_p
> > = parser->in_unbraced_export_declaration_p;
> > parser->in_unbraced_export_declaration_p = false;
> > + saved_auto_is_implicit_function_template_parm_p
> > + = parser->auto_is_implicit_function_template_parm_p;
> > + parser->auto_is_implicit_function_template_parm_p = false;
>
> On a related note it'd be nice to refactor all this saving/restoring
> code to use the RAII sentinel make_temp_override. (Such code predated
> gcc's move from C to C++ as the implementation language, which is why
> it's written in this way.)
>
> > +
> > /* 'this' from an enclosing non-static member function is unavailable.
> > */
> > tree saved_ccp = current_class_ptr;
> > tree saved_ccr = current_class_ref;
> > @@ -28571,9 +28576,10 @@ cp_parser_class_specifier (cp_parser* parser)
> > = saved_in_unbraced_linkage_specification_p;
> > parser->in_unbraced_export_declaration_p
> > = saved_in_unbraced_export_declaration_p;
> > + parser->auto_is_implicit_function_template_parm_p
> > + = saved_auto_is_implicit_function_template_parm_p;
> > current_class_ptr = saved_ccp;
> > current_class_ref = saved_ccr;
> > -
> > return type;
> > }
> >
> > diff --git a/gcc/testsuite/g++.dg/parse/auto-struct-param.C
> > b/gcc/testsuite/g++.dg/parse/auto-struct-param.C
> > new file mode 100644
> > index 00000000000..78573c68503
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/parse/auto-struct-param.C
> > @@ -0,0 +1,4 @@
> > +// PR c++/122112
> > +// { dg-do compile { target c++20 } }
> > +
> > +void func(struct { auto x; }); // { dg-error "" }
> > --
> > 2.51.0
> >
> >