aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2004-03-08 17:24:45 -0500
committerJason Merrill <jason@gcc.gnu.org>2004-03-08 17:24:45 -0500
commit38b305d0a3f999fcc52d5bcef25c2df1e6df4337 (patch)
tree56bedce81cd77320067da595944568deeb32f6dd
parent5a66cfb2f1274869df984c106783809c379950ec (diff)
downloadgcc-38b305d0a3f999fcc52d5bcef25c2df1e6df4337.zip
gcc-38b305d0a3f999fcc52d5bcef25c2df1e6df4337.tar.gz
gcc-38b305d0a3f999fcc52d5bcef25c2df1e6df4337.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c17
-rw-r--r--gcc/cp/parser.c27
-rw-r--r--gcc/cp/rtti.c6
-rw-r--r--gcc/testsuite/g++.dg/ext/attrib14.C13
6 files changed, 42 insertions, 33 deletions
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 <jason@redhat.com>
+
+ 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 <austern@apple.com>
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); }