The following invalid code snippet triggers an ICE on trunk: =============================== template<int> void foo() { int i, i = [] { virtual }(); } =============================== bug.cc: In function 'void foo()': bug.cc:4:3: error: redeclaration of 'int i' i = [] { virtual }(); ^ bug.cc:3:7: note: 'int i' previously declared here int i, ^ bug.cc: In lambda function: bug.cc:4:10: internal compiler error: tree check: expected class 'type', have 'exceptional' (error_mark) in template_class_depth, at cp/pt.c:394 i = [] { virtual }(); ^ 0x78a73c tree_class_check_failed(tree_node const*, tree_code_class, char const*, int, char const*) ../../gcc/gcc/tree.c:9385 0x635a64 tree_class_check(tree_node*, tree_code_class, char const*, int, char const*) ../../gcc/gcc/tree.h:3255 0x635a64 template_class_depth(tree_node*) ../../gcc/gcc/cp/pt.c:394 0x90b5c7 cp_parser_function_specifier_opt ../../gcc/gcc/cp/parser.c:13744 0x936708 cp_parser_decl_specifier_seq ../../gcc/gcc/cp/parser.c:13502 0x93bae0 cp_parser_simple_declaration ../../gcc/gcc/cp/parser.c:12916 0x93ca88 cp_parser_block_declaration ../../gcc/gcc/cp/parser.c:12863 0x93d4b9 cp_parser_declaration_statement ../../gcc/gcc/cp/parser.c:12457 0x91be7b cp_parser_statement ../../gcc/gcc/cp/parser.c:10906 0x91cdc0 cp_parser_statement_seq_opt ../../gcc/gcc/cp/parser.c:11255 0x91d897 cp_parser_lambda_body ../../gcc/gcc/cp/parser.c:10669 0x91d897 cp_parser_lambda_expression ../../gcc/gcc/cp/parser.c:10176 0x91d897 cp_parser_primary_expression ../../gcc/gcc/cp/parser.c:5257 0x9301bc cp_parser_postfix_expression ../../gcc/gcc/cp/parser.c:7026 0x930d90 cp_parser_unary_expression ../../gcc/gcc/cp/parser.c:8318 0x91117f cp_parser_cast_expression ../../gcc/gcc/cp/parser.c:9086 0x91198a cp_parser_binary_expression ../../gcc/gcc/cp/parser.c:9187 0x913164 cp_parser_assignment_expression ../../gcc/gcc/cp/parser.c:9476 0x9122bb cp_parser_constant_expression ../../gcc/gcc/cp/parser.c:9760 0x9130e7 cp_parser_initializer_clause ../../gcc/gcc/cp/parser.c:21890 Please submit a full bug report, [etc.] The regression was introduced between 2017-08-19 and 2017-09-02.
Confirmed with the top of trunk. ICE introduced in r251433: r251433 | jason | 2017-08-29 16:37:15 -0400 (Tue, 29 Aug 2017) | 28 lines Reimplement handling of lambdas in templates.
Created attachment 43457 [details] gcc8-pr84446.patch Untested fix.
Jakub, alternately, the below appears to work, and avoids having to catch the error_mark_node so late: Index: parser.c =================================================================== --- parser.c (revision 257801) +++ parser.c (working copy) @@ -19644,12 +19644,12 @@ cp_parser_init_declarator (cp_parser* parser, member templates. The former involves deferring parsing of the initializer until end of class as with default arguments. So right here we only handle the latter. */ - if (!member_p && processing_template_decl) + if (!member_p && processing_template_decl && decl != error_mark_node) start_lambda_scope (decl); initializer = cp_parser_initializer (parser, &is_direct_init, &is_non_constant_init); - if (!member_p && processing_template_decl) + if (!member_p && processing_template_decl && decl != error_mark_node) finish_lambda_scope (); if (initializer == error_mark_node) cp_parser_skip_to_end_of_statement (parser);
... well, I must add the diagnostic would be much more terse and similar to, eg, clang's.
Author: paolo Date: Tue Feb 20 09:02:12 2018 New Revision: 257841 URL: https://gcc.gnu.org/viewcvs?rev=257841&root=gcc&view=rev Log: /cp 2018-02-20 Paolo Carlini <paolo.carlini@oracle.com> PR c++/84446 * parser.c (cp_parser_init_declarator): Don't call start_lambda_scope on error_mark_node. /testsuite 2018-02-20 Paolo Carlini <paolo.carlini@oracle.com> PR c++/84446 * g++.dg/cpp0x/lambda/lambda-ice27.C: New. Added: trunk/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice27.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/parser.c trunk/gcc/testsuite/ChangeLog
Fixed.