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