In this testcase, we have (auto...), a function parameter pack without a declarator. Because there is no declarator, we were never hitting the code for turning the auto type into a template parameter pack, so the ... ended up being parsed as a C-style trailing ellipsis.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 476a47b844613603961cb1e7aedcbcc8601297b5 Author: Jason Merrill <ja...@redhat.com> Date: Mon Apr 2 07:45:02 2018 -0400 PR c++/64095 - auto... parameter pack. * parser.c (cp_parser_parameter_declaration): Handle turning autos into packs here. (cp_parser_parameter_declaration_list): Not here. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index e946d0b7229..d526a4eb365 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -21320,9 +21320,6 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) cp_parameter_declarator *parameter; tree decl = error_mark_node; bool parenthesized_p = false; - int template_parm_idx = (function_being_declared_is_template_p (parser)? - TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS - (current_template_parms)) : 0); /* Parse the parameter. */ parameter @@ -21336,22 +21333,6 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) if (parameter) { - /* If a function parameter pack was specified and an implicit template - parameter was introduced during cp_parser_parameter_declaration, - change any implicit parameters introduced into packs. */ - if (parser->implicit_template_parms - && parameter->declarator - && parameter->declarator->parameter_pack_p) - { - int latest_template_parm_idx = TREE_VEC_LENGTH - (INNERMOST_TEMPLATE_PARMS (current_template_parms)); - - if (latest_template_parm_idx != template_parm_idx) - parameter->decl_specifiers.type = convert_generic_types_to_packs - (parameter->decl_specifiers.type, - template_parm_idx, latest_template_parm_idx); - } - decl = grokdeclarator (parameter->declarator, ¶meter->decl_specifiers, PARM, @@ -21511,6 +21492,10 @@ cp_parser_parameter_declaration (cp_parser *parser, parser->type_definition_forbidden_message = G_("types may not be defined in parameter types"); + int template_parm_idx = (function_being_declared_is_template_p (parser) ? + TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS + (current_template_parms)) : 0); + /* Parse the declaration-specifiers. */ cp_token *decl_spec_token_start = cp_lexer_peek_token (parser->lexer); cp_parser_decl_specifier_seq (parser, @@ -21600,6 +21585,23 @@ cp_parser_parameter_declaration (cp_parser *parser, parameter pack expansion expression. Otherwise, leave the ellipsis for a C-style variadic function. */ token = cp_lexer_peek_token (parser->lexer); + + /* If a function parameter pack was specified and an implicit template + parameter was introduced during cp_parser_parameter_declaration, + change any implicit parameters introduced into packs. */ + if (parser->implicit_template_parms + && (token->type == CPP_ELLIPSIS + || (declarator && declarator->parameter_pack_p))) + { + int latest_template_parm_idx = TREE_VEC_LENGTH + (INNERMOST_TEMPLATE_PARMS (current_template_parms)); + + if (latest_template_parm_idx != template_parm_idx) + decl_specifiers.type = convert_generic_types_to_packs + (decl_specifiers.type, + template_parm_idx, latest_template_parm_idx); + } + if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) { tree type = decl_specifiers.type; diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic16.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic16.C new file mode 100644 index 00000000000..a9292253453 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic16.C @@ -0,0 +1,8 @@ +// PR c++/64095 +// { dg-do compile { target c++14 } } + +void f() +{ + [](auto...){}(); + [](auto&&...){}(); +} diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.C index ca0910be503..8f135358465 100644 --- a/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.C +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.C @@ -85,4 +85,4 @@ void Baz () // { dg-final { scan-assembler "_Z3eatIZ3FoovEUlPT_PT0_E4_Z3FoovEUlS1_S3_E5_EvRS0_RS2_:" } } // { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPfS3_E_EvRT_RT0_:" } } // { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPT_PT0_E0_EvRS3_RS5_:" } } -// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPT_zE1_EvRS3_RT0_:" } } +// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsDpPT_E1_EvRT_RT0_:" } }