https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84609
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jason at gcc dot gnu.org --- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- 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)."