From: Paolo Carlini Date: Tue, 23 Sep 2014 18:07:59 +0000 (+0000) Subject: re PR c++/61857 (An init-capturing lambda is parsed incorrectly when used in a braced... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9a9f3c8f1e05cec05b02b8b79e6a5531ba8dc377;p=gcc.git re PR c++/61857 (An init-capturing lambda is parsed incorrectly when used in a braced-init-list) /cp 2014-09-23 Paolo Carlini 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 PR c++/61857 * g++.dg/cpp1y/lambda-init10.C: New. From-SVN: r215528 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d6db39f9367..8058348bc8e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2014-09-23 Paolo Carlini + + 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 * semantics.c (finish_non_static_data_member): In diagnostic, give diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 9764794c881..33ad886524e 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c7be6d91646..206860a0f24 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-09-23 Paolo Carlini + + PR c++/61857 + * g++.dg/cpp1y/lambda-init10.C: New. + 2014-09-23 Jakub Jelinek 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 index 00000000000..230b3d173e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-init10.C @@ -0,0 +1,8 @@ +// PR c++/61857 +// { dg-do compile { target c++14 } } + +struct A { + A(int val) {} +}; + +A a{ [x=123]{ return x; }() };