re PR c++/5655 (Member redeclared within its class definition with a different access...
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
Thu, 25 Sep 2003 12:51:39 +0000 (12:51 +0000)
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>
Thu, 25 Sep 2003 12:51:39 +0000 (12:51 +0000)
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
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/access7.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.brendan/crash56.C

index 5804f9ff4dcff01104a1b1fde887ffbdfc398880..dcf2f665b63a00f6366ed26097564cea5de05c16 100644 (file)
@@ -1,3 +1,10 @@
+2003-09-25  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       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  <gcc@integrable-solutions.net>
 
        * cp-tree.h (scope_kind): Add new enumerator.
        (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.
index 4114aeaa24d354f6faef1540d01d5499ffd73285..776429096a8b476701dbf7c0c6108fdcfa8c850c 100644 (file)
@@ -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.  */
index dd4c187e043c9a2eab24895ba590e690fda47801..d9600501bfaf2ba85250ff4bfbd8a438d85ea700 100644 (file)
@@ -1,3 +1,9 @@
+2003-09-25  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       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  <zlaski@apple.com>
 
        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 (file)
index 0000000..2a7ca3c
--- /dev/null
@@ -0,0 +1,13 @@
+// { dg-do compile }
+
+// Origin: Paolo Carlini <pcarlini@unitus.it>
+
+// PR c++/5655: Access of member redeclaration.
+
+struct S {
+ class A;
+ template <class T> class B;
+private:
+ class A {};                   // { dg-error "different access" }
+ template <class T> class B {};        // { dg-error "different access" }
+};
index 133c9b9ff281e39295ea08fdbbd09b8e796a328e..243a2b620fea3e0937bd75eeb3267a12a27f3738 100644 (file)
@@ -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();