PR c++/64095 - auto... parameter pack.
authorJason Merrill <jason@redhat.com>
Mon, 2 Apr 2018 18:20:04 +0000 (14:20 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 2 Apr 2018 18:20:04 +0000 (14:20 -0400)
* parser.c (cp_parser_parameter_declaration): Handle turning autos
into packs here.
(cp_parser_parameter_declaration_list): Not here.

From-SVN: r259015

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic16.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.C

index d52a0dc33a3138e5e0e55021e5e9f463fc1b471b..e97442a5bea78d422e133c8861a5b031e7455c83 100644 (file)
@@ -1,3 +1,10 @@
+2018-04-02  Jason Merrill  <jason@redhat.com>
+
+       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.
+
 2018-03-31  Alexandre Oliva <aoliva@redhat.com>
 
        PR c++/85027
index e946d0b722926891a80306a00a5efbcf41acb854..d526a4eb3652e9e3e399c69bea0b8728bf3fa17d 100644 (file)
@@ -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,
                                 &parameter->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 (file)
index 0000000..a929225
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/64095
+// { dg-do compile { target c++14 } }
+
+void f()
+{
+  [](auto...){}();
+  [](auto&&...){}();
+}
index ca0910be5031ae2b49a7f35962890ec3cc4838ca..8f135358465beb97eb76b55384b26aa6e8b4a869 100644 (file)
@@ -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_:" } }