From: Jason Merrill Date: Mon, 8 Mar 2004 22:24:45 +0000 (-0500) Subject: re PR c++/13170 (ICE in build_base_path) X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=38b305d0a3f999fcc52d5bcef25c2df1e6df4337;p=platform%2Fupstream%2Fgcc.git re PR c++/13170 (ICE in build_base_path) PR c++/13170 * decl.c (xref_tag): Remove attribute handling. * cp-tree.h: Adjust prototype. * decl.c, parser.c, rtti.c: Adjust callers. * parser.c (cp_parser_class_head): Pass back attributes in the class head. (cp_parser_class_specifier): Adjust. From-SVN: r79129 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 70f15ff..c64bb21 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2004-03-08 Jason Merrill + + PR c++/13170 + * decl.c (xref_tag): Remove attribute handling. + * cp-tree.h: Adjust prototype. + * decl.c, parser.c, rtti.c: Adjust callers. + * parser.c (cp_parser_class_head): Pass back attributes in the + class head. + (cp_parser_class_specifier): Adjust. + 2004-03-08 Matt Austern PR debug/14079 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 36acc5a..55b077e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3647,7 +3647,7 @@ extern tree get_scope_of_declarator (tree); extern void grok_special_member_properties (tree); extern int grok_ctor_properties (tree, tree); extern bool grok_op_properties (tree, int, bool); -extern tree xref_tag (enum tag_types, tree, tree, bool, bool); +extern tree xref_tag (enum tag_types, tree, bool, bool); extern tree xref_tag_from_type (tree, tree, int); extern void xref_basetypes (tree, tree); extern tree start_enum (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 1c0ed25..8c2405f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -9303,8 +9303,7 @@ check_elaborated_type_specifier (enum tag_types tag_code, Define the tag as a forward-reference if it is not defined. If a declaration is given, process it here, and report an error if - multiple declarations are not identical. ATTRIBUTE is the attribute - appeared in this declaration. + multiple declarations are not identical. GLOBALIZE is false when this is also a definition. Only look in the current frame for the name (since C++ allows new names in any @@ -9314,7 +9313,7 @@ check_elaborated_type_specifier (enum tag_types tag_code, a set of template parameters. */ tree -xref_tag (enum tag_types tag_code, tree name, tree attributes, +xref_tag (enum tag_types tag_code, tree name, bool globalize, bool template_header_p) { enum tree_code code; @@ -9470,16 +9469,6 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes, redeclare_class_template (t, current_template_parms); } - /* Add attributes only when defining a class. */ - if (attributes) - { - /* The only place that xref_tag is called with non-null - attributes is in cp_parser_class_head(), when defining a - class. */ - my_friendly_assert (TYPE_ATTRIBUTES (t) == NULL_TREE, 20040113); - TYPE_ATTRIBUTES (t) = attributes; - } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); } @@ -9496,7 +9485,7 @@ xref_tag_from_type (tree old, tree id, int globalize) if (id == NULL_TREE) id = TYPE_IDENTIFIER (old); - return xref_tag (tag_kind, id, /*attributes=*/NULL_TREE, globalize, false); + return xref_tag (tag_kind, id, globalize, false); } /* REF is a type (named NAME), for which we have just seen some diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 9184f0e..b633653 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1523,7 +1523,7 @@ static tree cp_parser_class_name static tree cp_parser_class_specifier (cp_parser *); static tree cp_parser_class_head - (cp_parser *, bool *); + (cp_parser *, bool *, tree *); static enum tag_types cp_parser_class_key (cp_parser *); static void cp_parser_member_specification_opt @@ -9293,7 +9293,6 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, warning ("type attributes are honored only at type definition"); type = xref_tag (tag_type, identifier, - /*attributes=*/NULL_TREE, (is_friend || !is_declaration || cp_lexer_next_token_is_not (parser->lexer, @@ -11786,7 +11785,7 @@ cp_parser_class_specifier (cp_parser* parser) { cp_token *token; tree type; - tree attributes = NULL_TREE; + tree attributes; int has_trailing_semicolon; bool nested_name_specifier_p; unsigned saved_num_template_parameter_lists; @@ -11796,7 +11795,8 @@ cp_parser_class_specifier (cp_parser* parser) /* Parse the class-head. */ type = cp_parser_class_head (parser, - &nested_name_specifier_p); + &nested_name_specifier_p, + &attributes); /* If the class-head was a semantic disaster, skip the entire body of the class. */ if (!type) @@ -11839,17 +11839,14 @@ cp_parser_class_specifier (cp_parser* parser) missing trailing `;'. */ token = cp_lexer_peek_token (parser->lexer); has_trailing_semicolon = (token->type == CPP_SEMICOLON); - /* Look for attributes to apply to this class. */ + /* Look for trailing attributes to apply to this class. */ if (cp_parser_allow_gnu_extensions_p (parser)) - attributes = cp_parser_attributes_opt (parser); - /* If we got any attributes in class_head, xref_tag will stick them in - TREE_TYPE of the type. Grab them now. */ - if (type != error_mark_node) { - attributes = chainon (TYPE_ATTRIBUTES (type), attributes); - TYPE_ATTRIBUTES (type) = NULL_TREE; - type = finish_struct (type, attributes); + tree sub_attr = cp_parser_attributes_opt (parser); + attributes = chainon (attributes, sub_attr); } + if (type != error_mark_node) + type = finish_struct (type, attributes); if (pop_p) pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type))); /* If this class is not itself within the scope of another class, @@ -11956,7 +11953,8 @@ cp_parser_class_specifier (cp_parser* parser) static tree cp_parser_class_head (cp_parser* parser, - bool* nested_name_specifier_p) + bool* nested_name_specifier_p, + tree *attributes_p) { cp_token *token; tree nested_name_specifier; @@ -12183,7 +12181,7 @@ cp_parser_class_head (cp_parser* parser, /* If the class was unnamed, create a dummy name. */ if (!id) id = make_anon_name (); - type = xref_tag (class_key, id, attributes, /*globalize=*/false, + type = xref_tag (class_key, id, /*globalize=*/false, parser->num_template_parameter_lists); } else @@ -12267,6 +12265,7 @@ cp_parser_class_head (cp_parser* parser, end_specialization (); --parser->num_template_parameter_lists; } + *attributes_p = attributes; return type; } diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index fb611a7..e9c0616 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -120,7 +120,7 @@ init_rtti_processing (void) push_namespace (std_identifier); type_info_type_node = xref_tag (class_type, get_identifier ("type_info"), - /*attributes=*/NULL_TREE, true, false); + true, false); pop_namespace (); const_type_info_type = build_qualified_type (type_info_type_node, TYPE_QUAL_CONST); @@ -635,7 +635,6 @@ build_dynamic_cast_1 (tree type, tree expr) push_nested_namespace (ns); tinfo_ptr = xref_tag (class_type, get_identifier ("__class_type_info"), - /*attributes=*/NULL_TREE, true, false); tinfo_ptr = build_pointer_type @@ -777,7 +776,7 @@ tinfo_base_init (tree desc, tree target) push_nested_namespace (abi_node); real_type = xref_tag (class_type, TINFO_REAL_NAME (desc), - /*attributes=*/NULL_TREE, true, false); + true, false); pop_nested_namespace (abi_node); if (!COMPLETE_TYPE_P (real_type)) @@ -1373,7 +1372,6 @@ emit_support_tinfos (void) push_nested_namespace (abi_node); bltn_type = xref_tag (class_type, get_identifier ("__fundamental_type_info"), - /*attributes=*/NULL_TREE, true, false); pop_nested_namespace (abi_node); if (!COMPLETE_TYPE_P (bltn_type)) diff --git a/gcc/testsuite/g++.dg/ext/attrib14.C b/gcc/testsuite/g++.dg/ext/attrib14.C new file mode 100644 index 0000000..1b22729 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib14.C @@ -0,0 +1,13 @@ +// PR c++/13170 +// The bogus attribute is ignored, but was in TYPE_ATTRIBUTES during parsing of the class, +// causing some variants to have it and some not. + +struct __attribute__((bogus)) A +{ + virtual ~A(); + void foo(const A&); + void bar(const A&); +}; // { dg-warning "ignored" "" } + +void A::foo(const A&) {} +void A::bar(const A& a) { foo(a); }