From patchwork Thu Dec 6 14:36:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: C++ PATCH for c++/54947 (wrong error with lambda in init-list) X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 204251 Message-Id: <50C0AD60.5050301@redhat.com> To: gcc-patches List Date: Thu, 06 Dec 2012 09:36:16 -0500 From: Jason Merrill List-Id: When we're parsing tentatively, we shouldn't do something, like requiring a constant-expression, that will produce an error. This patch delays checking whether the expression is constant until we know that we're actually looking at a designator. Tested x86_64-pc-linux-gnu, applying to trunk. commit 77da076687dac5f406f4e929497a8b7b747d287a Author: Jason Merrill Date: Wed Dec 5 17:47:52 2012 -0500 PR c++/54947 * parser.c (cp_parser_initializer_list): Don't require an expression in [] to be constant until we know it's a C99 designator. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 190b8d9..a010f1f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -17923,11 +17923,14 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p) /* In C++11, [ could start a lambda-introducer. */ cp_parser_parse_tentatively (parser); cp_lexer_consume_token (parser->lexer); - designator = cp_parser_constant_expression (parser, false, NULL); + bool non_const = false; + 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) + require_potential_rvalue_constant_expression (designator); } else designator = NULL_TREE; diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-initlist2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-initlist2.C new file mode 100644 index 0000000..daaa339 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-initlist2.C @@ -0,0 +1,27 @@ +// PR c++/54947 +// { dg-options -std=gnu++11 } + +struct X +{ + template + X(L) + { } +}; + +template + void + test() + { + int i = 0; + + A a_ok_1( [=] { return i; } ); // OK + A a_ok_2( [i] { return i; } ); // OK + + A a_err_1{ [i] { return i; } }; // error + A a_err_2{ [=] { return i; } }; // error + } + +int main() +{ + test(); +}