Here we were returning OK from cp_parser_lambda_declarator_opt even though we had encountered parse errors, and so parsing the inner lambda aborted due to seeing an error_mark_node expression-statement without ever having emitted any errors.
Fixed by clearing OK if there were parse errors. Tested x86_64-pc-linux-gnu, applying to trunk and 6.
commit 17fea383f9a2861903ae6d144b3ba7e6a4bf191a Author: Jason Merrill <ja...@redhat.com> Date: Wed Jul 20 17:03:50 2016 -0400 PR c++/70781 - ICE on ill-formed lambda. * parser.c (cp_parser_lambda_expression): Unset OK if there was an error parsing the lambda-declarator. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 9bdb108..b71b9e5 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -9771,10 +9771,12 @@ cp_parser_lambda_expression (cp_parser* parser) ok &= cp_parser_lambda_declarator_opt (parser, lambda_expr); + if (ok && cp_parser_error_occurred (parser)) + ok = false; + if (ok) { - if (!cp_parser_error_occurred (parser) - && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE) + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE) && cp_parser_start_tentative_firewall (parser)) start = token; cp_parser_lambda_body (parser, lambda_expr); diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice16.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice16.C new file mode 100644 index 0000000..e94a0b6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice16.C @@ -0,0 +1,8 @@ +// PR c++/70781 +// { dg-do compile { target c++11 } } + +template < typename T > +void foo () +{ + T ([=] (S) { [=] {}; }); // { dg-error "" } +}