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

Reply via email to