This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 29138
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 3 Oct 2006 11:08:36 -0700
- Subject: C++ PATCH: PR 29138
- Reply-to: mark at codesourcery dot com
This patch fixes PR c++/29138, a rejects-valid regression in the C++
front-end. Old-style "access declarations" didn't work when the
declaration referred to a type, rather than to a data or function
member. The reason was that the access-declaration code was in
grokfield, and that's not used for types. This patch fixes the
problem by having the parser detect access declarations as a grammar
rule, thereby handling types and non-types identically.
Tested on x86_64-unknown-linux-gnu, applied on the mainline and on the
4.1 branch.
--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713
2006-10-03 Mark Mitchell <mark@codesourcery.com>
PR c++/29138
* decl2.c (grokfield): Don't handle access declarations here.
* parser.c (cp_parser_using_declaration): Handle access
declarations too.
(cp_parser_block_declaration): Adjust calls to
cp_parser_using_declaration.
(cp_parser_member_declaration): Likewise. Use
cp_parser_using_declaration to look for access_declarations.
2006-10-03 Mark Mitchell <mark@codesourcery.com>
PR c++/29138
* g++.dg/inherit/access8.C: New test.
* g++.dg/template/dtor4.C: Tweak error messages.
Index: gcc/cp/decl2.c
===================================================================
--- gcc/cp/decl2.c (revision 117359)
+++ gcc/cp/decl2.c (working copy)
@@ -769,16 +769,6 @@ grokfield (const cp_declarator *declarat
const char *asmspec = 0;
int flags = LOOKUP_ONLYCONVERTING;
- if (!declspecs->any_specifiers_p
- && declarator->kind == cdk_id
- && declarator->u.id.qualifying_scope
- && TYPE_P (declarator->u.id.qualifying_scope)
- && IS_AGGR_TYPE (declarator->u.id.qualifying_scope)
- && TREE_CODE (declarator->u.id.unqualified_name) == IDENTIFIER_NODE)
- /* Access declaration */
- return do_class_using_decl (declarator->u.id.qualifying_scope,
- declarator->u.id.unqualified_name);
-
if (init
&& TREE_CODE (init) == TREE_LIST
&& TREE_VALUE (init) == error_mark_node
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c (revision 117360)
+++ gcc/cp/parser.c (working copy)
@@ -1518,8 +1518,8 @@ static tree cp_parser_qualified_namespac
(cp_parser *);
static void cp_parser_namespace_alias_definition
(cp_parser *);
-static void cp_parser_using_declaration
- (cp_parser *);
+static bool cp_parser_using_declaration
+ (cp_parser *, bool);
static void cp_parser_using_directive
(cp_parser *);
static void cp_parser_asm_definition
@@ -7184,7 +7184,8 @@ cp_parser_block_declaration (cp_parser *
cp_parser_using_directive (parser);
/* Otherwise, it's a using-declaration. */
else
- cp_parser_using_declaration (parser);
+ cp_parser_using_declaration (parser,
+ /*access_declaration_p=*/false);
}
/* If the next keyword is `__label__' we have a label declaration. */
else if (token1->keyword == RID_LABEL)
@@ -10582,14 +10583,21 @@ cp_parser_qualified_namespace_specifier
return cp_parser_namespace_name (parser);
}
-/* Parse a using-declaration.
+/* Parse a using-declaration, or, if ACCESS_DECLARATION_P is true, an
+ access declaration.
using-declaration:
using typename [opt] :: [opt] nested-name-specifier unqualified-id ;
- using :: unqualified-id ; */
+ using :: unqualified-id ;
-static void
-cp_parser_using_declaration (cp_parser* parser)
+ access-declaration:
+ qualified-id ;
+
+ */
+
+static bool
+cp_parser_using_declaration (cp_parser* parser,
+ bool access_declaration_p)
{
cp_token *token;
bool typename_p = false;
@@ -10598,18 +10606,23 @@ cp_parser_using_declaration (cp_parser*
tree identifier;
tree qscope;
- /* Look for the `using' keyword. */
- cp_parser_require_keyword (parser, RID_USING, "`using'");
-
- /* Peek at the next token. */
- token = cp_lexer_peek_token (parser->lexer);
- /* See if it's `typename'. */
- if (token->keyword == RID_TYPENAME)
+ if (access_declaration_p)
+ cp_parser_parse_tentatively (parser);
+ else
{
- /* Remember that we've seen it. */
- typename_p = true;
- /* Consume the `typename' token. */
- cp_lexer_consume_token (parser->lexer);
+ /* Look for the `using' keyword. */
+ cp_parser_require_keyword (parser, RID_USING, "`using'");
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* See if it's `typename'. */
+ if (token->keyword == RID_TYPENAME)
+ {
+ /* Remember that we've seen it. */
+ typename_p = true;
+ /* Consume the `typename' token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
}
/* Look for the optional global scope qualification. */
@@ -10643,6 +10656,14 @@ cp_parser_using_declaration (cp_parser*
/*declarator_p=*/true,
/*optional_p=*/false);
+ if (access_declaration_p)
+ {
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ cp_parser_simulate_error (parser);
+ if (!cp_parser_parse_definitely (parser))
+ return false;
+ }
+
/* The function we call to handle a using-declaration is different
depending on what scope we are in. */
if (qscope == error_mark_node || identifier == error_mark_node)
@@ -10676,6 +10697,8 @@ cp_parser_using_declaration (cp_parser*
/* Look for the final `;'. */
cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+
+ return true;
}
/* Parse a using-directive.
@@ -13551,8 +13574,8 @@ cp_parser_member_declaration (cp_parser*
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
{
/* Parse the using-declaration. */
- cp_parser_using_declaration (parser);
-
+ cp_parser_using_declaration (parser,
+ /*access_declaration_p=*/false);
return;
}
@@ -13572,6 +13595,9 @@ cp_parser_member_declaration (cp_parser*
return;
}
+ if (cp_parser_using_declaration (parser, /*access_declaration=*/true))
+ return;
+
/* Parse the decl-specifier-seq. */
cp_parser_decl_specifier_seq (parser,
CP_PARSER_FLAGS_OPTIONAL,
Index: gcc/testsuite/g++.dg/inherit/access8.C
===================================================================
--- gcc/testsuite/g++.dg/inherit/access8.C (revision 0)
+++ gcc/testsuite/g++.dg/inherit/access8.C (revision 0)
@@ -0,0 +1,25 @@
+// PR c++/29138
+
+class A
+{
+public:
+ int i;
+ class A1
+ {
+ int j;
+ };
+};
+
+class B : private A
+{
+public:
+ A::i;
+ A::A1;
+};
+
+void
+f ()
+{
+ B b;
+ B::A1 a1;
+}
Index: gcc/testsuite/g++.dg/template/dtor4.C
===================================================================
--- gcc/testsuite/g++.dg/template/dtor4.C (revision 117384)
+++ gcc/testsuite/g++.dg/template/dtor4.C (working copy)
@@ -5,5 +5,5 @@
template<int> struct A
{
- ~A<0>(); // { dg-error "declaration" }
+ ~A<0>(); // { dg-error "parse error|declaration" }
};