Bug 84446 - [8 Regression] ICE with broken lambda
Summary: [8 Regression] ICE with broken lambda
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.0
: P4 normal
Target Milestone: 8.0
Assignee: Not yet assigned to anyone
URL:
Keywords: error-recovery, ice-on-invalid-code
Depends on:
Blocks:
 
Reported: 2018-02-18 20:17 UTC by Volker Reichelt
Modified: 2018-02-20 09:03 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-02-18 00:00:00


Attachments
gcc8-pr84446.patch (587 bytes, patch)
2018-02-19 12:13 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Volker Reichelt 2018-02-18 20:17:29 UTC
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.
Comment 1 Martin Sebor 2018-02-18 23:28:22 UTC
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.
Comment 2 Jakub Jelinek 2018-02-19 12:13:24 UTC
Created attachment 43457 [details]
gcc8-pr84446.patch

Untested fix.
Comment 3 Paolo Carlini 2018-02-19 16:15:37 UTC
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);
Comment 4 Paolo Carlini 2018-02-19 16:18:24 UTC
... well, I must add the diagnostic would be much more terse and similar to, eg, clang's.
Comment 5 paolo@gcc.gnu.org 2018-02-20 09:02:44 UTC
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
Comment 6 Paolo Carlini 2018-02-20 09:03:52 UTC
Fixed.