From 37d407a1cf20fec15802c5ab158f8256af5ad00d Mon Sep 17 00:00:00 2001 From: Kriang Lerdsuwanakij Date: Thu, 25 Sep 2003 12:51:39 +0000 Subject: [PATCH] re PR c++/5655 (Member redeclared within its class definition with a different access specifier is not rejected) PR c++/5655 * parser.c (cp_parser_check_access_in_redeclaration): New function. (cp_parser_member_declaration): Use it. (cp_parser_template_declaration_after_export): Likewise. * g++.dg/parse/access7.C: New test. * g++.old-deja/g++.brendan/crash56.C: Fix redeclaration error. From-SVN: r71771 --- gcc/cp/ChangeLog | 9 +++++- gcc/cp/parser.c | 28 ++++++++++++++++++- gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/g++.dg/parse/access7.C | 13 +++++++++ .../g++.old-deja/g++.brendan/crash56.C | 3 +- 5 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/access7.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5804f9ff4dc..dcf2f665b63 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2003-09-25 Kriang Lerdsuwanakij + + PR c++/5655 + * parser.c (cp_parser_check_access_in_redeclaration): New function. + (cp_parser_member_declaration): Use it. + (cp_parser_template_declaration_after_export): Likewise. + 2003-09-22 Gabriel Dos Reis * cp-tree.h (scope_kind): Add new enumerator. @@ -706,7 +713,7 @@ (do_friend): Adjust add_friend call. * decl.c (grokdeclarator): Adjust make_friend_class call. * parser.c (cp_parser_member_declaration): Likewise. - (cp_parser_template_declaration_after_exp): Likewise. + (cp_parser_template_declaration_after_export): Likewise. * pt.c (instantiate_class_template): Adjust make_friend_class and add_friend call. * cp-tree.h (make_friend_class): Adjust declaration. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 4114aeaa24d..776429096a8 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1651,6 +1651,8 @@ static enum tag_types cp_parser_token_is_class_key (cp_token *); static void cp_parser_check_class_key (enum tag_types, tree type); +static void cp_parser_check_access_in_redeclaration + (tree type); static bool cp_parser_optional_template_keyword (cp_parser *); static void cp_parser_pre_parsed_nested_name_specifier @@ -11870,6 +11872,8 @@ cp_parser_member_declaration (cp_parser* parser) /* Add it to the class. */ finish_member_declaration (decl); } + else + cp_parser_check_access_in_redeclaration (TYPE_NAME (type)); } } else @@ -13657,7 +13661,12 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p) /* If this is a member template declaration, let the front end know. */ if (member_p && !friend_p && decl) - decl = finish_member_template_decl (decl); + { + if (TREE_CODE (decl) == TYPE_DECL) + cp_parser_check_access_in_redeclaration (decl); + + decl = finish_member_template_decl (decl); + } else if (friend_p && decl && TREE_CODE (decl) == TYPE_DECL) make_friend_class (current_class_type, TREE_TYPE (decl), /*complain=*/true); @@ -14265,6 +14274,23 @@ cp_parser_check_class_key (enum tag_types class_key, tree type) type); } +/* Issue an error message if DECL is redeclared with differnt + access than its original declaration [class.access.spec/3]. + This applies to nested classes and nested class templates. + [class.mem/1]. */ + +static void cp_parser_check_access_in_redeclaration (tree decl) +{ + if (!CLASS_TYPE_P (TREE_TYPE (decl))) + return; + + if ((TREE_PRIVATE (decl) + != (current_access_specifier == access_private_node)) + || (TREE_PROTECTED (decl) + != (current_access_specifier == access_protected_node))) + error ("%D redeclared with different access", decl); +} + /* Look for the `template' keyword, as a syntactic disambiguator. Return TRUE iff it is present, in which case it will be consumed. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dd4c187e043..d9600501bfa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2003-09-25 Kriang Lerdsuwanakij + + PR c++/5655 + * g++.dg/parse/access7.C: New test. + * g++.old-deja/g++.brendan/crash56.C: Fix redeclaration error. + 2003-09-24 Ziemowit Laski MERGE OF objc-improvements-branch into MAINLINE: diff --git a/gcc/testsuite/g++.dg/parse/access7.C b/gcc/testsuite/g++.dg/parse/access7.C new file mode 100644 index 00000000000..2a7ca3c42ac --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/access7.C @@ -0,0 +1,13 @@ +// { dg-do compile } + +// Origin: Paolo Carlini + +// PR c++/5655: Access of member redeclaration. + +struct S { + class A; + template class B; +private: + class A {}; // { dg-error "different access" } + template class B {}; // { dg-error "different access" } +}; diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C index 133c9b9ff28..243a2b620fe 100644 --- a/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C +++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C @@ -5,6 +5,8 @@ const bool FALSE = 0; const bool TRUE = 1; class ListDProto { +protected: + class link; public: ListDProto(); ListDProto(const ListDProto&); @@ -15,7 +17,6 @@ public: void clear(); void remove_head(); void remove_tail(); - class link; class Vix { public: Vix(); -- 2.30.2