PR c++/89686 - mixing init-capture and simple-capture in lambda.
authorMarek Polacek <polacek@redhat.com>
Wed, 13 Mar 2019 19:58:20 +0000 (19:58 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Wed, 13 Mar 2019 19:58:20 +0000 (19:58 +0000)
* parser.c (cp_parser_lambda_introducer): Give error when combining
init-capture and simple-capture.

* g++.dg/cpp2a/lambda-pack-init2.C: New test.

From-SVN: r269659

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp2a/lambda-pack-init2.C [new file with mode: 0644]

index 2e06623..fa0fdea 100644 (file)
@@ -8,6 +8,10 @@
        (cp_parser_constructor_declarator_p): Add FLAGS parameter.  Pass it to
        cp_parser_type_specifier.
 
+       PR c++/89686 - mixing init-capture and simple-capture in lambda.
+       * parser.c (cp_parser_lambda_introducer): Give error when combining
+       init-capture and simple-capture.
+
 2019-03-11  Jason Merrill  <jason@redhat.com>
 
        PR c++/86521 - wrong overload resolution with ref-qualifiers.
index 8244366..14da1a1 100644 (file)
@@ -10609,12 +10609,13 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
        }
 
       bool init_pack_expansion = false;
+      location_t ellipsis_loc = UNKNOWN_LOCATION;
       if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
        {
-         location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+         ellipsis_loc = cp_lexer_peek_token (parser->lexer)->location;
          if (cxx_dialect < cxx2a)
-           pedwarn (loc, 0, "pack init-capture only available with "
-                            "%<-std=c++2a%> or %<-std=gnu++2a%>");
+           pedwarn (ellipsis_loc, 0, "pack init-capture only available with "
+                    "%<-std=c++2a%> or %<-std=gnu++2a%>");
          cp_lexer_consume_token (parser->lexer);
          init_pack_expansion = true;
        }
@@ -10719,8 +10720,21 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
 
          if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
            {
+             location_t loc = cp_lexer_peek_token (parser->lexer)->location;
              cp_lexer_consume_token (parser->lexer);
              capture_init_expr = make_pack_expansion (capture_init_expr);
+             if (init_pack_expansion)
+               {
+                 /* If what follows is an initializer, the second '...' is
+                    invalid.  But for cases like [...xs...], the first one
+                    is invalid.  */
+                 if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)
+                     || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
+                     || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+                   ellipsis_loc = loc;
+                 error_at (ellipsis_loc, "too many %<...%> in lambda capture");
+                 continue;
+               }
            }
        }
 
index afb61b4..ed025c9 100644 (file)
@@ -1,3 +1,8 @@
+2019-03-13  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/89686 - mixing init-capture and simple-capture in lambda.
+       * g++.dg/cpp2a/lambda-pack-init2.C: New test.
+
 2019-03-13  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/89601
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-pack-init2.C b/gcc/testsuite/g++.dg/cpp2a/lambda-pack-init2.C
new file mode 100644 (file)
index 0000000..55d689d
--- /dev/null
@@ -0,0 +1,22 @@
+// PR c++/89686
+// { dg-do compile { target c++2a } }
+
+template <typename... Ts>
+void foo(Ts... xs)
+{
+  int i = 10;
+  [...xs...]{}(); // { dg-error "4:too many ..... in lambda capture" }
+  [...xs...=xs]{}(); // { dg-error "9:too many ..... in lambda capture|expected" }
+  [xs...]{}();
+  [...xs=xs]{}();
+
+  [i, ...xs...]{}(); // { dg-error "7:too many ..... in lambda capture" }
+  [i, ...xs...=xs]{}(); // { dg-error "12:too many ..... in lambda capture|expected" }
+  [i, xs...]{}();
+  [i, ...xs=xs]{}();
+}
+
+int main()
+{
+ foo(0, 1, 2);
+}