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
This commit is contained in:
parent
a3b11faf7e
commit
cfb14840b8
4 changed files with 77 additions and 32 deletions
|
@ -1,3 +1,15 @@
|
|||
2018-01-18 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
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 <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/78344
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2018-01-18 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/83824
|
||||
* g++.dg/cpp0x/pr83824.C: New test.
|
||||
|
||||
2018-01-17 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
* gcc.target/powerpc/gnuattr1.c: New test to make sure we set the
|
||||
|
|
9
gcc/testsuite/g++.dg/cpp0x/pr83824.C
Normal file
9
gcc/testsuite/g++.dg/cpp0x/pr83824.C
Normal file
|
@ -0,0 +1,9 @@
|
|||
// PR c++/83824
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
void
|
||||
foo ()
|
||||
{
|
||||
if (alignas(1 alignas(1))) // { dg-error "expected" }
|
||||
;
|
||||
}
|
Loading…
Add table
Reference in a new issue