Hi,

in this C++14 rejects valid issue, we reject the testcase with "‘x’ was not declared in this scope", because in cp_parser_initializer_list we tentatively try to parse what follows the '[' as a cp_parser_constant_expression. As far as I can see, we can easily solve the issue with the approach already used in many other places, thus don't even try a constant if the ']' isn't followed by '='. Tested x86_64-linux.

Thanks!
Paolo.

PS: I tried to once reuse as is the new cp_parser_skip_to_closing_square_bracket in cp_parser_lambda_introducer but we get more redundant diagnostic eg, at the end of g++.old-deja/g++.other/crash28.C. In fact, the context is slightly different, because in cp_parser_skip_to_closing_square_bracket we are in error recovery. I suppose we can further investigate this later...
/cp
2014-09-23  Paolo Carlini  <paolo.carl...@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.carl...@oracle.com>

        PR c++/61857
        * g++.dg/cpp1y/lambda-init10.C: New.
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 215496)
+++ cp/parser.c (working copy)
@@ -2487,6 +2487,10 @@ static cp_declarator * cp_parser_make_indirect_dec
   (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* no
   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, boo
          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: testsuite/g++.dg/cpp1y/lambda-init10.C
===================================================================
--- testsuite/g++.dg/cpp1y/lambda-init10.C      (revision 0)
+++ testsuite/g++.dg/cpp1y/lambda-init10.C      (working copy)
@@ -0,0 +1,8 @@
+// PR c++/61857
+// { dg-do compile { target c++14 } }
+
+struct A { 
+  A(int val) {}
+};
+
+A a{ [x=123]{ return x; }() }; 

Reply via email to