From cfb14840b842698f12ad82ab42ed4b8445af8992 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 18 Jan 2018 00:42:36 +0100 Subject: [PATCH] re PR c++/83824 (ICE on invalid C++ code with alignas: in chainon, at tree.c:3037) PR c++/83824 * parser.c (attr_chainon): New function. (cp_parser_label_for_labeled_statement, cp_parser_decl_specifier_seq, cp_parser_namespace_definition, cp_parser_init_declarator, cp_parser_type_specifier_seq, cp_parser_parameter_declaration, cp_parser_gnu_attributes_opt): Use it. (cp_parser_member_declaration, cp_parser_objc_class_ivars, cp_parser_objc_struct_declaration): Likewise. Don't reset prefix_attributes if attributes is error_mark_node. * g++.dg/cpp0x/pr83824.C: New test. From-SVN: r256823 --- gcc/cp/ChangeLog | 12 ++++++ gcc/cp/parser.c | 83 ++++++++++++++++++++++-------------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/cpp0x/pr83824.C | 9 ++++ 4 files changed, 77 insertions(+), 32 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/pr83824.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5978a64..998e0b9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2018-01-18 Jakub Jelinek + + PR c++/83824 + * parser.c (attr_chainon): New function. + (cp_parser_label_for_labeled_statement, cp_parser_decl_specifier_seq, + cp_parser_namespace_definition, cp_parser_init_declarator, + cp_parser_type_specifier_seq, cp_parser_parameter_declaration, + cp_parser_gnu_attributes_opt): Use it. + (cp_parser_member_declaration, cp_parser_objc_class_ivars, + cp_parser_objc_struct_declaration): Likewise. Don't reset + prefix_attributes if attributes is error_mark_node. + 2018-01-17 Paolo Carlini PR c++/78344 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 80d65a8..222db0c 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -10908,6 +10908,18 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr, "attributes at the beginning of statement are ignored"); } +/* Append ATTR to attribute list ATTRS. */ + +static tree +attr_chainon (tree attrs, tree attr) +{ + if (attrs == error_mark_node) + return error_mark_node; + if (attr == error_mark_node) + return error_mark_node; + return chainon (attrs, attr); +} + /* Parse the label for a labeled-statement, i.e. identifier : @@ -11027,7 +11039,7 @@ cp_parser_label_for_labeled_statement (cp_parser* parser, tree attributes) else if (!cp_parser_parse_definitely (parser)) ; else - attributes = chainon (attributes, attrs); + attributes = attr_chainon (attributes, attrs); } if (attributes != NULL_TREE) @@ -13394,8 +13406,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser, else { decl_specs->std_attributes - = chainon (decl_specs->std_attributes, - attrs); + = attr_chainon (decl_specs->std_attributes, attrs); if (decl_specs->locations[ds_std_attribute] == 0) decl_specs->locations[ds_std_attribute] = token->location; } @@ -13403,9 +13414,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser, } } - decl_specs->attributes - = chainon (decl_specs->attributes, - attrs); + decl_specs->attributes + = attr_chainon (decl_specs->attributes, attrs); if (decl_specs->locations[ds_attribute] == 0) decl_specs->locations[ds_attribute] = token->location; continue; @@ -18471,7 +18481,7 @@ cp_parser_namespace_definition (cp_parser* parser) identifier = cp_parser_identifier (parser); /* Parse any attributes specified after the identifier. */ - attribs = chainon (attribs, cp_parser_attributes_opt (parser)); + attribs = attr_chainon (attribs, cp_parser_attributes_opt (parser)); } if (cp_lexer_next_token_is_not (parser->lexer, CPP_SCOPE)) @@ -19633,7 +19643,7 @@ cp_parser_init_declarator (cp_parser* parser, decl = grokfield (declarator, decl_specifiers, initializer, !is_non_constant_init, /*asmspec=*/NULL_TREE, - chainon (attributes, prefix_attributes)); + attr_chainon (attributes, prefix_attributes)); if (decl && TREE_CODE (decl) == FUNCTION_DECL) cp_parser_save_default_args (parser, decl); cp_finalize_omp_declare_simd (parser, decl); @@ -21007,9 +21017,9 @@ cp_parser_type_specifier_seq (cp_parser* parser, /* Check for attributes first. */ if (cp_next_tokens_can_be_attribute_p (parser)) { - type_specifier_seq->attributes = - chainon (type_specifier_seq->attributes, - cp_parser_attributes_opt (parser)); + type_specifier_seq->attributes + = attr_chainon (type_specifier_seq->attributes, + cp_parser_attributes_opt (parser)); continue; } @@ -21491,8 +21501,8 @@ cp_parser_parameter_declaration (cp_parser *parser, parser->default_arg_ok_p = saved_default_arg_ok_p; /* After the declarator, allow more attributes. */ decl_specifiers.attributes - = chainon (decl_specifiers.attributes, - cp_parser_attributes_opt (parser)); + = attr_chainon (decl_specifiers.attributes, + cp_parser_attributes_opt (parser)); /* If the declarator is a template parameter pack, remember that and clear the flag in the declarator itself so we don't get errors @@ -23653,13 +23663,13 @@ cp_parser_member_declaration (cp_parser* parser) late_attributes = cp_parser_attributes_opt (parser); } - attributes = chainon (attributes, late_attributes); + attributes = attr_chainon (attributes, late_attributes); /* Remember which attributes are prefix attributes and which are not. */ first_attribute = attributes; /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); + attributes = attr_chainon (prefix_attributes, attributes); /* Create the bitfield declaration. */ decl = grokbitfield (identifier @@ -23715,7 +23725,7 @@ cp_parser_member_declaration (cp_parser* parser) which are not. */ first_attribute = attributes; /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); + attributes = attr_chainon (prefix_attributes, attributes); /* If it's an `=', then we have a constant-initializer or a pure-specifier. It is not correct to parse the @@ -23837,10 +23847,13 @@ cp_parser_member_declaration (cp_parser* parser) cp_finalize_oacc_routine (parser, decl, false); /* Reset PREFIX_ATTRIBUTES. */ - while (attributes && TREE_CHAIN (attributes) != first_attribute) - attributes = TREE_CHAIN (attributes); - if (attributes) - TREE_CHAIN (attributes) = NULL_TREE; + if (attributes != error_mark_node) + { + while (attributes && TREE_CHAIN (attributes) != first_attribute) + attributes = TREE_CHAIN (attributes); + if (attributes) + TREE_CHAIN (attributes) = NULL_TREE; + } /* If there is any qualification still in effect, clear it now; we will be starting fresh with the next declarator. */ @@ -24909,7 +24922,7 @@ cp_parser_gnu_attributes_opt (cp_parser* parser) cp_parser_skip_to_end_of_statement (parser); /* Add these new attributes to the list. */ - attributes = chainon (attributes, attribute_list); + attributes = attr_chainon (attributes, attribute_list); } return attributes; @@ -30114,7 +30127,7 @@ cp_parser_objc_class_ivars (cp_parser* parser) which are not. */ first_attribute = attributes; /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); + attributes = attr_chainon (prefix_attributes, attributes); if (width) /* Create the bitfield declaration. */ @@ -30130,10 +30143,13 @@ cp_parser_objc_class_ivars (cp_parser* parser) objc_add_instance_variable (decl); /* Reset PREFIX_ATTRIBUTES. */ - while (attributes && TREE_CHAIN (attributes) != first_attribute) - attributes = TREE_CHAIN (attributes); - if (attributes) - TREE_CHAIN (attributes) = NULL_TREE; + if (attributes != error_mark_node) + { + while (attributes && TREE_CHAIN (attributes) != first_attribute) + attributes = TREE_CHAIN (attributes); + if (attributes) + TREE_CHAIN (attributes) = NULL_TREE; + } token = cp_lexer_peek_token (parser->lexer); @@ -30666,8 +30682,8 @@ cp_parser_objc_struct_declaration (cp_parser *parser) which are not. */ first_attribute = attributes; /* Combine the attributes. */ - attributes = chainon (prefix_attributes, attributes); - + attributes = attr_chainon (prefix_attributes, attributes); + decl = grokfield (declarator, &declspecs, NULL_TREE, /*init_const_expr_p=*/false, NULL_TREE, attributes); @@ -30676,10 +30692,13 @@ cp_parser_objc_struct_declaration (cp_parser *parser) return error_mark_node; /* Reset PREFIX_ATTRIBUTES. */ - while (attributes && TREE_CHAIN (attributes) != first_attribute) - attributes = TREE_CHAIN (attributes); - if (attributes) - TREE_CHAIN (attributes) = NULL_TREE; + if (attributes != error_mark_node) + { + while (attributes && TREE_CHAIN (attributes) != first_attribute) + attributes = TREE_CHAIN (attributes); + if (attributes) + TREE_CHAIN (attributes) = NULL_TREE; + } DECL_CHAIN (decl) = decls; decls = decl; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ad23ad7..c4a4e3e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-01-18 Jakub Jelinek + + PR c++/83824 + * g++.dg/cpp0x/pr83824.C: New test. + 2018-01-17 Michael Meissner * gcc.target/powerpc/gnuattr1.c: New test to make sure we set the diff --git a/gcc/testsuite/g++.dg/cpp0x/pr83824.C b/gcc/testsuite/g++.dg/cpp0x/pr83824.C new file mode 100644 index 0000000..9474e1e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr83824.C @@ -0,0 +1,9 @@ +// PR c++/83824 +// { dg-do compile { target c++11 } } + +void +foo () +{ + if (alignas(1 alignas(1))) // { dg-error "expected" } + ; +} -- 2.7.4