We parse the initializer for an init-capture as an initializer, which
checks for any unexpanded parameter packs.  Normally we avoid that
error in a lambda by checking whether we're in a lambda, but at this
point we haven't entered the lambda scope yet.

Jakub, if we end up needing an RC3 it would be nice to get this into
8.1, but if not it's fine to wait for 8.2.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 2009e6d79c38c4867600156ab6b457c0e664927f
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon Apr 30 13:33:12 2018 -0400

            PR c++/85305 - pack in lambda init-capture.
    
            * parser.c (cp_parser_initializer): Add subexpression_p parm; don't
            check_for_bare_parameter_packs in a subexpression.
            (cp_parser_lambda_introducer): Use it.

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index d8ce28a6d61..b839232bcbe 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -2243,7 +2243,7 @@ static tree cp_parser_default_argument
 static void cp_parser_function_body
   (cp_parser *, bool);
 static tree cp_parser_initializer
-  (cp_parser *, bool *, bool *);
+  (cp_parser *, bool *, bool *, bool = false);
 static cp_expr cp_parser_initializer_clause
   (cp_parser *, bool *);
 static cp_expr cp_parser_braced_list
@@ -10358,7 +10358,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
 		     "lambda capture initializers "
 		     "only available with -std=c++14 or -std=gnu++14");
 	  capture_init_expr = cp_parser_initializer (parser, &direct,
-						     &non_constant);
+						     &non_constant, true);
 	  explicit_init_p = true;
 	  if (capture_init_expr == NULL_TREE)
 	    {
@@ -21860,7 +21860,7 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser,
 
 static tree
 cp_parser_initializer (cp_parser* parser, bool* is_direct_init,
-		       bool* non_constant_p)
+		       bool* non_constant_p, bool subexpression_p)
 {
   cp_token *token;
   tree init;
@@ -21907,7 +21907,7 @@ cp_parser_initializer (cp_parser* parser, bool* is_direct_init,
       init = error_mark_node;
     }
 
-  if (check_for_bare_parameter_packs (init))
+  if (!subexpression_p && check_for_bare_parameter_packs (init))
     init = error_mark_node;
 
   return init;
diff --git a/gcc/testsuite/g++.dg/cpp1z/fold-lambda2.C b/gcc/testsuite/g++.dg/cpp1z/fold-lambda2.C
new file mode 100644
index 00000000000..e93f55f7fd8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/fold-lambda2.C
@@ -0,0 +1,8 @@
+// PR c++/85305
+// { dg-additional-options -std=c++17 }
+
+template <int... Is>
+void foo()
+{
+  ([i = Is]{}(), ...); 
+}

Reply via email to