re PR c++/61857 (An init-capturing lambda is parsed incorrectly when used in a braced...
authorPaolo Carlini <paolo.carlini@oracle.com>
Tue, 23 Sep 2014 18:07:59 +0000 (18:07 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Tue, 23 Sep 2014 18:07:59 +0000 (18:07 +0000)
/cp
2014-09-23  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/61857
* parser.c (cp_parser_skip_to_closing_square_bracket,
cp_parser_array_designator_p): New.
(cp_parser_initializer_list): Use the latter.

/testsuite
2014-09-23  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/61857
* g++.dg/cpp1y/lambda-init10.C: New.

From-SVN: r215528

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

index d6db39f9367bd647bc5e9f08e2cbff440f041276..8058348bc8ed9fee5bbfa64ebaf3c100898ba1fc 100644 (file)
@@ -1,3 +1,10 @@
+2014-09-23  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/61857
+       * parser.c (cp_parser_skip_to_closing_square_bracket,
+       cp_parser_array_designator_p): New.
+       (cp_parser_initializer_list): Use the latter.
+
 2014-09-22  Jason Merrill  <jason@redhat.com>
 
        * semantics.c (finish_non_static_data_member): In diagnostic, give
index 9764794c881428774eb1375161cbf3fa9d4facc7..33ad886524e76e27e84b5a03fe15a094a5bce746 100644 (file)
@@ -2487,6 +2487,10 @@ static cp_declarator * cp_parser_make_indirect_declarator
   (enum tree_code, tree, cp_cv_quals, cp_declarator *, tree);
 static bool cp_parser_compound_literal_p
   (cp_parser *);
+static bool cp_parser_array_designator_p
+  (cp_parser *);
+static bool cp_parser_skip_to_closing_square_bracket
+  (cp_parser *);
 
 /* Returns nonzero if we are parsing tentatively.  */
 
@@ -19157,6 +19161,69 @@ cp_parser_braced_list (cp_parser* parser, bool* non_constant_p)
   return initializer;
 }
 
+/* Consume tokens up to, and including, the next non-nested closing `]'.
+   Returns true iff we found a closing `]'.  */
+
+static bool
+cp_parser_skip_to_closing_square_bracket (cp_parser *parser)
+{
+  unsigned square_depth = 0;
+
+  while (true)
+    {
+      cp_token * token = cp_lexer_peek_token (parser->lexer);
+
+      switch (token->type)
+       {
+       case CPP_EOF:
+       case CPP_PRAGMA_EOL:
+         /* If we've run out of tokens, then there is no closing `]'.  */
+         return false;
+
+        case CPP_OPEN_SQUARE:
+          ++square_depth;
+          break;
+
+        case CPP_CLOSE_SQUARE:
+         if (!square_depth--)
+           {
+             cp_lexer_consume_token (parser->lexer);
+             return true;
+           }
+         break;
+
+       default:
+         break;
+       }
+
+      /* Consume the token.  */
+      cp_lexer_consume_token (parser->lexer);
+    }
+}
+
+/* Return true if we are looking at an array-designator, false otherwise.  */
+
+static bool
+cp_parser_array_designator_p (cp_parser *parser)
+{
+  /* Consume the `['.  */
+  cp_lexer_consume_token (parser->lexer);
+
+  cp_lexer_save_tokens (parser->lexer);
+
+  /* Skip tokens until the next token is a closing square bracket.
+     If we find the closing `]', and the next token is a `=', then
+     we are looking at an array designator.  */
+  bool array_designator_p
+    = (cp_parser_skip_to_closing_square_bracket (parser)
+       && cp_lexer_next_token_is (parser->lexer, CPP_EQ));
+  
+  /* Roll back the tokens we skipped.  */
+  cp_lexer_rollback_tokens (parser->lexer);
+
+  return array_designator_p;
+}
+
 /* Parse an initializer-list.
 
    initializer-list:
@@ -19235,10 +19302,20 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
          bool non_const = false;
 
          cp_parser_parse_tentatively (parser);
-         cp_lexer_consume_token (parser->lexer);
-         designator = cp_parser_constant_expression (parser, true, &non_const);
-         cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
-         cp_parser_require (parser, CPP_EQ, RT_EQ);
+
+         if (!cp_parser_array_designator_p (parser))
+           {
+             cp_parser_simulate_error (parser);
+             designator = NULL_TREE;
+           }
+         else
+           {
+             designator = cp_parser_constant_expression (parser, true,
+                                                         &non_const);
+             cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+             cp_parser_require (parser, CPP_EQ, RT_EQ);
+           }
+
          if (!cp_parser_parse_definitely (parser))
            designator = NULL_TREE;
          else if (non_const)
index c7be6d9164605a441201fc05b103e2d0c74e6a7a..206860a0f244d4c8cc695cbcb966f9c9eafa1e60 100644 (file)
@@ -1,3 +1,8 @@
+2014-09-23  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/61857
+       * g++.dg/cpp1y/lambda-init10.C: New.
+
 2014-09-23  Jakub Jelinek  <jakub@redhat.com>
 
        PR fortran/63331
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init10.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init10.C
new file mode 100644 (file)
index 0000000..230b3d1
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/61857
+// { dg-do compile { target c++14 } }
+
+struct A { 
+  A(int val) {}
+};
+
+A a{ [x=123]{ return x; }() };