This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: Fix PR c++/13305
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 5 Dec 2003 22:46:44 -0800
- Subject: C++ PATCH: Fix PR c++/13305
- Reply-to: mark at codesourcery dot com
This patch fixes c++/13305. The new parser was failing to accept
attributes in elaborated type specifiers, which the old parser did
accept.
Tested on i686-pc-linux-gnu, applied on the mainline.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2003-12-05 Danny Smith <dannysmith@gcc.gnu.org>
Mark Mitchell <mark@codesourcery.com>
PR c++/13305
* parser.c (cp_parser_elaborated_type_specifier): Accept
attributes.
2003-12-05 Mark Mitchell <mark@codesourcery.com>
PR c++/13305
* g++.dg/ext/attrib9.C: New test.
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.128
diff -c -5 -p -r1.128 parser.c
*** cp/parser.c 6 Dec 2003 04:59:49 -0000 1.128
--- cp/parser.c 6 Dec 2003 06:50:15 -0000
*************** cp_parser_type_name (cp_parser* parser)
*** 8645,8654 ****
--- 8645,8662 ----
enum :: [opt] nested-name-specifier [opt] identifier
typename :: [opt] nested-name-specifier identifier
typename :: [opt] nested-name-specifier template [opt]
template-id
+ GNU extension:
+
+ elaborated-type-specifier:
+ class-key attributes :: [opt] nested-name-specifier [opt] identifier
+ class-key attributes :: [opt] nested-name-specifier [opt]
+ template [opt] template-id
+ enum attributes :: [opt] nested-name-specifier [opt] identifier
+
If IS_FRIEND is TRUE, then this elaborated-type-specifier is being
declared `friend'. If IS_DECLARATION is TRUE, then this
elaborated-type-specifier appears in a decl-specifiers-seq, i.e.,
something is being declared.
*************** cp_parser_elaborated_type_specifier (cp_
*** 8660,8677 ****
--- 8668,8688 ----
bool is_declaration)
{
enum tag_types tag_type;
tree identifier;
tree type = NULL_TREE;
+ tree attributes = NULL_TREE;
/* See if we're looking at the `enum' keyword. */
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ENUM))
{
/* Consume the `enum' token. */
cp_lexer_consume_token (parser->lexer);
/* Remember that it's an enumeration type. */
tag_type = enum_type;
+ /* Parse the attributes. */
+ attributes = cp_parser_attributes_opt (parser);
}
/* Or, it might be `typename'. */
else if (cp_lexer_next_token_is_keyword (parser->lexer,
RID_TYPENAME))
{
*************** cp_parser_elaborated_type_specifier (cp_
*** 8687,8696 ****
--- 8698,8709 ----
else
{
tag_type = cp_parser_class_key (parser);
if (tag_type == none_type)
return error_mark_node;
+ /* Parse the attributes. */
+ attributes = cp_parser_attributes_opt (parser);
}
/* Look for the `::' operator. */
cp_parser_global_scope_opt (parser,
/*current_scope_valid_p=*/false);
*************** cp_parser_elaborated_type_specifier (cp_
*** 8856,8866 ****
Also, `new struct S' or `sizeof (struct S)' never results in the
definition of a new type; a new type can only be declared in a
declaration context. */
type = xref_tag (tag_type, identifier,
! /*attributes=*/NULL_TREE,
(is_friend
|| !is_declaration
|| cp_lexer_next_token_is_not (parser->lexer,
CPP_SEMICOLON)),
parser->num_template_parameter_lists);
--- 8869,8879 ----
Also, `new struct S' or `sizeof (struct S)' never results in the
definition of a new type; a new type can only be declared in a
declaration context. */
type = xref_tag (tag_type, identifier,
! attributes,
(is_friend
|| !is_declaration
|| cp_lexer_next_token_is_not (parser->lexer,
CPP_SEMICOLON)),
parser->num_template_parameter_lists);
Index: testsuite/g++.dg/ext/attrib9.C
===================================================================
RCS file: testsuite/g++.dg/ext/attrib9.C
diff -N testsuite/g++.dg/ext/attrib9.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/ext/attrib9.C 6 Dec 2003 06:50:48 -0000
***************
*** 0 ****
--- 1,5 ----
+ class __attribute__((unused)) C;
+ struct __attribute__((unused)) S;
+ union __attribute__((unused)) U;
+ enum e {};
+ enum __attribute__((unused)) e;