Bug 84609 - [8 Regression] internal compiler error: in cp_parser_abort_tentative_parse, at cp/parser.c:28960 (cp_parser_member_declaration())
Summary: [8 Regression] internal compiler error: in cp_parser_abort_tentative_parse, a...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.0.1
: P3 normal
Target Milestone: 8.0
Assignee: Jakub Jelinek
URL:
Keywords: ice-on-invalid-code
Depends on:
Blocks:
 
Reported: 2018-02-28 08:26 UTC by Vegard Nossum
Modified: 2018-02-28 19:04 UTC (History)
3 users (show)

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


Attachments
gcc8-pr84609.patch (1.97 KB, patch)
2018-02-28 14:25 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Vegard Nossum 2018-02-28 08:26:41 UTC
Input:

struct s {
  int a __attribute__((aligned([](char *) {})));
};

Output:

$ xgcc -x c++ -std=c++14 -O3 -Wall -fpermissive -c -
<stdin>:2:47: internal compiler error: in cp_parser_abort_tentative_parse, at cp/parser.c:28960
0xe87f54 cp_parser_abort_tentative_parse
        /home/vegard/git/gcc/gcc/cp/parser.c:28959
0xfdb287 cp_parser_member_declaration
        /home/vegard/git/gcc/gcc/cp/parser.c:23597
0xf10d9b cp_parser_member_specification_opt
        /home/vegard/git/gcc/gcc/cp/parser.c:23308
0xf10d9b cp_parser_class_specifier_1
        /home/vegard/git/gcc/gcc/cp/parser.c:22450
0xf1fcbb cp_parser_class_specifier
        /home/vegard/git/gcc/gcc/cp/parser.c:22702
0xf1fcbb cp_parser_type_specifier
        /home/vegard/git/gcc/gcc/cp/parser.c:16708
0xf8520a cp_parser_decl_specifier_seq
        /home/vegard/git/gcc/gcc/cp/parser.c:13573
0xfa0d60 cp_parser_simple_declaration
        /home/vegard/git/gcc/gcc/cp/parser.c:12882
0xfa8c88 cp_parser_block_declaration
        /home/vegard/git/gcc/gcc/cp/parser.c:12827
0xffb8d5 cp_parser_declaration
        /home/vegard/git/gcc/gcc/cp/parser.c:12724
0xff298b cp_parser_declaration_seq_opt
        /home/vegard/git/gcc/gcc/cp/parser.c:12600
0xff3fb3 cp_parser_translation_unit
        /home/vegard/git/gcc/gcc/cp/parser.c:4559
0xff3fb3 c_parse_file()
        /home/vegard/git/gcc/gcc/cp/parser.c:38820
0x15a0525 c_common_parse_file()
        /home/vegard/git/gcc/gcc/c-family/c-opts.c:1132

Version:

xgcc (GCC) 8.0.1 20180204 (experimental)

built from git fdae6180ad24fa6303fa046114f3e4b66b8db34d

Version 7.3.0 don't seem to be affected AFAICS.

Test case was reduced by C-Reduce.

It looks related to bug #84606 to me because of the lambda-inside-attribute, but the stack trace is completely different.
Comment 1 Martin Liška 2018-02-28 10:05:48 UTC
Confirmed, started with r253281.
Comment 2 Jakub Jelinek 2018-02-28 11:17:23 UTC
The:
23637		  /* The following code wants to know early if it is a bit-field
23638		     or some other declaration.  Attributes can appear before
23639		     the `:' token, but are hopefully rare enough that the
23640		     simplicity of the tentative lookup pays off.  */
23641		  if (cp_next_tokens_can_be_attribute_p (parser)
23642		      || (token->type == CPP_NAME
23643			  && cp_nth_tokens_can_be_attribute_p (parser, 2)
23644			  && (named_bitfld = true)))
23645		    {
23646		      cp_parser_parse_tentatively (parser);
23647		      if (named_bitfld)
23648			cp_lexer_consume_token (parser->lexer);
23649		      cp_parser_attributes_opt (parser);
23650		      token = cp_lexer_peek_token (parser->lexer);
23651		      is_bitfld = cp_lexer_next_token_is (parser->lexer, CPP_COLON);
23652		      cp_parser_abort_tentative_parse (parser);
23653		    }
code assumes that during parsing of the attribute(s) we don't commit the tentative parsing and it can be unconditionally undone, which is not the case here, because in:
#0  cp_parser_commit_to_tentative_parse (parser=0x7ffff7ff6bd0) at ../../gcc/cp/parser.c:28976
#1  0x00000000009d267a in cp_parser_parameter_declaration (parser=0x7ffff7ff6bd0, template_parm_p=false, parenthesized_p=0x7fffffffc26f)
    at ../../gcc/cp/parser.c:21547
#2  0x00000000009d1ed0 in cp_parser_parameter_declaration_list (parser=0x7ffff7ff6bd0, is_error=0x7fffffffc317) at ../../gcc/cp/parser.c:21305
#3  0x00000000009d1d20 in cp_parser_parameter_declaration_clause (parser=0x7ffff7ff6bd0) at ../../gcc/cp/parser.c:21228
#4  0x00000000009bca81 in cp_parser_lambda_declarator_opt (parser=0x7ffff7ff6bd0, lambda_expr=<lambda_expr 0x7fffefdb4040>)
    at ../../gcc/cp/parser.c:10517
#5  0x00000000009bbe71 in cp_parser_lambda_expression (parser=0x7ffff7ff6bd0) at ../../gcc/cp/parser.c:10172
#6  0x00000000009b1217 in cp_parser_primary_expression (parser=0x7ffff7ff6bd0, address_p=false, cast_p=false, template_arg_p=false, 
    decltype_p=false, idk=0x7fffffffc8ec) at ../../gcc/cp/parser.c:5257
#7  0x00000000009b539c in cp_parser_postfix_expression (parser=0x7ffff7ff6bd0, address_p=false, cast_p=false, member_access_only_p=false, 
    decltype_p=false, pidk_return=0x0) at ../../gcc/cp/parser.c:7026
#8  0x00000000009b89aa in cp_parser_unary_expression (parser=0x7ffff7ff6bd0, pidk=0x0, address_p=false, cast_p=false, decltype_p=false)
    at ../../gcc/cp/parser.c:8318
#9  0x00000000009b9ac6 in cp_parser_cast_expression (parser=0x7ffff7ff6bd0, address_p=false, cast_p=false, decltype_p=false, pidk=0x0)
    at ../../gcc/cp/parser.c:9086
#10 0x00000000009b9bc3 in cp_parser_binary_expression (parser=0x7ffff7ff6bd0, cast_p=false, no_toplevel_fold_p=false, decltype_p=false, 
    prec=PREC_NOT_OPERATOR, pidk=0x0) at ../../gcc/cp/parser.c:9187
#11 0x00000000009ba9a0 in cp_parser_assignment_expression (parser=0x7ffff7ff6bd0, pidk=0x0, cast_p=false, decltype_p=false)
    at ../../gcc/cp/parser.c:9482
#12 0x00000000009b758c in cp_parser_parenthesized_expression_list (parser=0x7ffff7ff6bd0, is_attribute_list=1, cast_p=false, 
    allow_expansion_p=false, non_constant_p=0x0, close_paren_loc=0x0, wrap_locations_p=false) at ../../gcc/cp/parser.c:7760
#13 0x00000000009d99f3 in cp_parser_gnu_attribute_list (parser=0x7ffff7ff6bd0) at ../../gcc/cp/parser.c:25047
#14 0x00000000009d9839 in cp_parser_gnu_attributes_opt (parser=0x7ffff7ff6bd0) at ../../gcc/cp/parser.c:24965
#15 0x00000000009d9772 in cp_parser_attributes_opt (parser=0x7ffff7ff6bd0) at ../../gcc/cp/parser.c:24922
#16 0x00000000009d74d9 in cp_parser_member_declaration (parser=0x7ffff7ff6bd0) at ../../gcc/cp/parser.c:23649

we in:
21531	      /* After seeing a decl-specifier-seq, if the next token is not a
21532		 "(", there is no possibility that the code is a valid
21533		 expression.  Therefore, if parsing tentatively, we commit at
21534		 this point.  */
21535	      if (!parser->in_template_argument_list_p
21536		  /* In an expression context, having seen:
21537	
21538		       (int((char ...
21539	
21540		     we cannot be sure whether we are looking at a
21541		     function-type (taking a "char" as a parameter) or a cast
21542		     of some object of type "char" to "int".  */
21543		  && !parser->in_type_id_in_expr_p
21544		  && cp_parser_uncommitted_to_tentative_parse_p (parser)
21545		  && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE)
21546		  && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
21547		cp_parser_commit_to_tentative_parse (parser);

commit to tentative parse.  Not really sure what to do here though, can we just reject statement-expressions and lambdas in attribute arguments?
I guess for the non-standard attributes we can do anything we want, but for standard attributes like alignas we don't really have a choice, right?
If we could restrict it, we could do something similar to parser->in_template_argument_list_p when parsing attribute arguments.

Or I can just try to implement what I talked about when submitting the patch:
"As I said on IRC, I hope [[/__attribute__/alignas early is rare enough that the tentative parsing shouldn't be a big deal, if it is, we could add some cheaper function that allows us to skip over attributes (return a peek offset after the attributes given a starting peek offset)."
Comment 3 Jakub Jelinek 2018-02-28 14:25:32 UTC
Created attachment 43529 [details]
gcc8-pr84609.patch

Untested fix.
Comment 4 Jason Merrill 2018-02-28 17:15:21 UTC
(In reply to Jakub Jelinek from comment #3)
> Created attachment 43529 [details]
> gcc8-pr84609.patch
> 
> Untested fix.

Looks good.
Comment 5 Jakub Jelinek 2018-02-28 18:58:09 UTC
Author: jakub
Date: Wed Feb 28 18:57:38 2018
New Revision: 258080

URL: https://gcc.gnu.org/viewcvs?rev=258080&root=gcc&view=rev
Log:
	PR c++/84609
	* parser.c (cp_parser_attributes_opt): Formatting fix.
	(cp_parser_skip_balanced_tokens, cp_parser_skip_gnu_attributes_opt,
	cp_parser_skip_std_attribute_spec_seq, cp_parser_skip_attributes_opt):
	New functions.
	(cp_parser_member_declaration): Use cp_parser_skip_attributes_opt
	instead of tentative parse to peek over optional attribute tokens
	to check for CPP_COLON after them.

	* g++.dg/cpp0x/pr84609.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/pr84609.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/parser.c
    trunk/gcc/testsuite/ChangeLog
Comment 6 Jakub Jelinek 2018-02-28 19:04:17 UTC
Fixed.