This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++] PATCH for 13170 to class attribute handling
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 08 Mar 2004 17:20:16 -0500
- Subject: [C++] PATCH for 13170 to class attribute handling
PR 13170 is caused by the parser temporarily storing attributes specified
in the class head in TYPE_ATTRIBUTES, and then removing them later if they
don't apply. As a result, we were winding up with variants both with and
without the attribute, causing confusion and death.
This patch changes the parser to store the class head attributes in a local
variable in cp_parser_class_specifier rather than in the type itself. As a
side-effect, we can remove the attribute handling from xref_tag, where it
really doesn't belong.
Tested x86_64-pc-linux-gnu, applied to trunk and 3.4. Test in
g++.dg/ext/attrib14.C.
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.
*** cp-tree.h.~1~ 2004-02-24 13:30:54.000000000 -0500
--- cp-tree.h 2004-03-08 15:50:35.000000000 -0500
*************** extern tree get_scope_of_declarator
*** 3647,3653 ****
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_from_type (tree, tree, int);
extern void xref_basetypes (tree, tree);
extern tree start_enum (tree);
--- 3647,3653 ----
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, bool, bool);
extern tree xref_tag_from_type (tree, tree, int);
extern void xref_basetypes (tree, tree);
extern tree start_enum (tree);
*** decl.c.~1~ 2004-03-05 17:37:41.000000000 -0500
--- decl.c 2004-03-08 15:50:38.000000000 -0500
*************** check_elaborated_type_specifier (enum ta
*** 9303,9310 ****
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.
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
--- 9303,9309 ----
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.
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
*************** check_elaborated_type_specifier (enum ta
*** 9314,9320 ****
a set of template parameters. */
tree
! xref_tag (enum tag_types tag_code, tree name, tree attributes,
bool globalize, bool template_header_p)
{
enum tree_code code;
--- 9313,9319 ----
a set of template parameters. */
tree
! xref_tag (enum tag_types tag_code, tree name,
bool globalize, bool template_header_p)
{
enum tree_code code;
*************** xref_tag (enum tag_types tag_code, tree
*** 9470,9485 ****
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);
}
--- 9469,9474 ----
*************** xref_tag_from_type (tree old, tree id, i
*** 9496,9502 ****
if (id == NULL_TREE)
id = TYPE_IDENTIFIER (old);
! return xref_tag (tag_kind, id, /*attributes=*/NULL_TREE, globalize, false);
}
/* REF is a type (named NAME), for which we have just seen some
--- 9485,9491 ----
if (id == NULL_TREE)
id = TYPE_IDENTIFIER (old);
! return xref_tag (tag_kind, id, globalize, false);
}
/* REF is a type (named NAME), for which we have just seen some
*** parser.c.~1~ 2004-03-05 17:37:42.000000000 -0500
--- parser.c 2004-03-08 15:51:30.000000000 -0500
*************** static tree cp_parser_class_name
*** 1523,1529 ****
static tree cp_parser_class_specifier
(cp_parser *);
static tree cp_parser_class_head
! (cp_parser *, bool *);
static enum tag_types cp_parser_class_key
(cp_parser *);
static void cp_parser_member_specification_opt
--- 1523,1529 ----
static tree cp_parser_class_specifier
(cp_parser *);
static tree cp_parser_class_head
! (cp_parser *, bool *, tree *);
static enum tag_types cp_parser_class_key
(cp_parser *);
static void cp_parser_member_specification_opt
*************** cp_parser_elaborated_type_specifier (cp_
*** 9293,9299 ****
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,
--- 9293,9298 ----
*************** cp_parser_class_specifier (cp_parser* pa
*** 11786,11792 ****
{
cp_token *token;
tree type;
! tree attributes = NULL_TREE;
int has_trailing_semicolon;
bool nested_name_specifier_p;
unsigned saved_num_template_parameter_lists;
--- 11785,11791 ----
{
cp_token *token;
tree type;
! tree attributes;
int has_trailing_semicolon;
bool nested_name_specifier_p;
unsigned saved_num_template_parameter_lists;
*************** cp_parser_class_specifier (cp_parser* pa
*** 11796,11802 ****
/* Parse the class-head. */
type = cp_parser_class_head (parser,
! &nested_name_specifier_p);
/* If the class-head was a semantic disaster, skip the entire body
of the class. */
if (!type)
--- 11795,11802 ----
/* Parse the class-head. */
type = cp_parser_class_head (parser,
! &nested_name_specifier_p,
! &attributes);
/* If the class-head was a semantic disaster, skip the entire body
of the class. */
if (!type)
*************** cp_parser_class_specifier (cp_parser* pa
*** 11839,11855 ****
missing trailing `;'. */
token = cp_lexer_peek_token (parser->lexer);
has_trailing_semicolon = (token->type == CPP_SEMICOLON);
! /* Look for 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);
}
if (pop_p)
pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type)));
/* If this class is not itself within the scope of another class,
--- 11839,11852 ----
missing trailing `;'. */
token = cp_lexer_peek_token (parser->lexer);
has_trailing_semicolon = (token->type == CPP_SEMICOLON);
! /* Look for trailing attributes to apply to this class. */
if (cp_parser_allow_gnu_extensions_p (parser))
{
! 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,
*************** cp_parser_class_specifier (cp_parser* pa
*** 11956,11962 ****
static tree
cp_parser_class_head (cp_parser* parser,
! bool* nested_name_specifier_p)
{
cp_token *token;
tree nested_name_specifier;
--- 11953,11960 ----
static tree
cp_parser_class_head (cp_parser* parser,
! bool* nested_name_specifier_p,
! tree *attributes_p)
{
cp_token *token;
tree nested_name_specifier;
*************** cp_parser_class_head (cp_parser* parser,
*** 12183,12189 ****
/* If the class was unnamed, create a dummy name. */
if (!id)
id = make_anon_name ();
! type = xref_tag (class_key, id, attributes, /*globalize=*/false,
parser->num_template_parameter_lists);
}
else
--- 12181,12187 ----
/* If the class was unnamed, create a dummy name. */
if (!id)
id = make_anon_name ();
! type = xref_tag (class_key, id, /*globalize=*/false,
parser->num_template_parameter_lists);
}
else
*************** cp_parser_class_head (cp_parser* parser,
*** 12267,12272 ****
--- 12265,12271 ----
end_specialization ();
--parser->num_template_parameter_lists;
}
+ *attributes_p = attributes;
return type;
}
*** rtti.c.~1~ 2004-02-10 18:59:02.000000000 -0500
--- rtti.c 2004-03-08 15:50:36.000000000 -0500
*************** init_rtti_processing (void)
*** 120,126 ****
push_namespace (std_identifier);
type_info_type_node
= xref_tag (class_type, get_identifier ("type_info"),
! /*attributes=*/NULL_TREE, true, false);
pop_namespace ();
const_type_info_type = build_qualified_type (type_info_type_node,
TYPE_QUAL_CONST);
--- 120,126 ----
push_namespace (std_identifier);
type_info_type_node
= xref_tag (class_type, get_identifier ("type_info"),
! true, false);
pop_namespace ();
const_type_info_type = build_qualified_type (type_info_type_node,
TYPE_QUAL_CONST);
*************** build_dynamic_cast_1 (tree type, tree ex
*** 635,641 ****
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
--- 635,640 ----
*************** tinfo_base_init (tree desc, tree target)
*** 777,783 ****
push_nested_namespace (abi_node);
real_type = xref_tag (class_type, TINFO_REAL_NAME (desc),
! /*attributes=*/NULL_TREE, true, false);
pop_nested_namespace (abi_node);
if (!COMPLETE_TYPE_P (real_type))
--- 776,782 ----
push_nested_namespace (abi_node);
real_type = xref_tag (class_type, TINFO_REAL_NAME (desc),
! true, false);
pop_nested_namespace (abi_node);
if (!COMPLETE_TYPE_P (real_type))
*************** emit_support_tinfos (void)
*** 1373,1379 ****
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))
--- 1372,1377 ----