re PR c++/11645 (Failure to deal with using and private inheritance)
authorMark Mitchell <mark@codesourcery.com>
Wed, 23 Jul 2003 21:28:24 +0000 (21:28 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 23 Jul 2003 21:28:24 +0000 (21:28 +0000)
PR c++/11645
* cp-tree.h (accessible_base_p): Declare.
* call.c (build_over_call): Use it.
* search.c (accessible_base_p): New function, split out from ...
(lookup_base): ... here.

PR c++/11645
* g++.dg/inherit/access4.C: New test.

From-SVN: r69724

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/search.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/inherit/access4.C [new file with mode: 0644]

index 1ef39bff24801fb1a71ee68dece3a9052b15d53a..3314b35c1588209b6645bc823dd43e977dbc6c83 100644 (file)
@@ -1,5 +1,11 @@
 2003-07-23  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/11645
+       * cp-tree.h (accessible_base_p): Declare.
+       * call.c (build_over_call): Use it.
+       * search.c (accessible_base_p): New function, split out from ...
+       (lookup_base): ... here.
+
        PR c++/11517
        * call.c (build_conditional_expr): Use perform_implicit_conversion
        and error_operand_p.  Robustify.
index dddd7b80866a823d0447cd4e470988acfd9859ce..11e8d2e0cabdc05690f88fc435a7e9d2d16627dc 100644 (file)
@@ -4414,12 +4414,17 @@ build_over_call (struct z_candidate *cand, int flags)
                                       TREE_VALUE (arg),
                                       cand->conversion_path,
                                       1);
+      /* Check that the base class is accessible.  */
+      if (!accessible_base_p (TREE_TYPE (argtype), 
+                             BINFO_TYPE (cand->conversion_path)))
+       error ("`%T' is not an accessible base of `%T'",
+              BINFO_TYPE (cand->conversion_path),
+              TREE_TYPE (argtype));
       /* If fn was found by a using declaration, the conversion path
          will be to the derived class, not the base declaring fn. We
          must convert from derived to base.  */
       base_binfo = lookup_base (TREE_TYPE (TREE_TYPE (converted_arg)),
                                TREE_TYPE (parmtype), ba_ignore, NULL);
-      
       converted_arg = build_base_path (PLUS_EXPR, converted_arg,
                                       base_binfo, 1);
       
index b46675272871fb63ece42f9345a4e205997f79a2..15bcea07eee7f1281a76803b4556af477708753c 100644 (file)
@@ -4025,6 +4025,7 @@ extern void emit_support_tinfos (void);
 extern bool emit_tinfo_decl (tree);
 
 /* in search.c */
+extern bool accessible_base_p (tree, tree);
 extern tree lookup_base (tree, tree, base_access, base_kind *);
 extern int types_overlap_p                     (tree, tree);
 extern tree get_vbase                          (tree, tree);
index 10b52164cd0e748105c4c3d41a9cef89f972f95f..3f8e2daf8a86fbb1fa510bbc6337fec47f178145 100644 (file)
@@ -231,6 +231,28 @@ lookup_base_r (tree binfo, tree base, base_access access,
   return found;
 }
 
+/* Returns true if type BASE is accessible in T.  (BASE is known to be
+   a base class of T.)  */
+
+bool
+accessible_base_p (tree t, tree base)
+{
+  tree decl;
+
+  /* [class.access.base]
+
+     A base class is said to be accessible if an invented public
+     member of the base class is accessible.  */
+  /* Rather than inventing a public member, we use the implicit
+     public typedef created in the scope of every class.  */
+  decl = TYPE_FIELDS (base);
+  while (!DECL_SELF_REFERENCE_P (decl))
+    decl = TREE_CHAIN (decl);
+  while (ANON_AGGR_TYPE_P (t))
+    t = TYPE_CONTEXT (t);
+  return accessible_p (t, decl);
+}
+
 /* Lookup BASE in the hierarchy dominated by T.  Do access checking as
    ACCESS specifies.  Return the binfo we discover.  If KIND_PTR is
    non-NULL, fill with information about what kind of base we
@@ -287,39 +309,24 @@ lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr)
        break;
 
       default:
-       if (access != ba_ignore
+       if ((access & ~ba_quiet) != ba_ignore
            /* If BASE is incomplete, then BASE and TYPE are probably
               the same, in which case BASE is accessible.  If they
               are not the same, then TYPE is invalid.  In that case,
               there's no need to issue another error here, and
               there's no implicit typedef to use in the code that
               follows, so we skip the check.  */
-           && COMPLETE_TYPE_P (base))
+           && COMPLETE_TYPE_P (base)
+           && !accessible_base_p (t, base))
          {
-           tree decl;
-
-           /* [class.access.base]
-
-              A base class is said to be accessible if an invented public
-              member of the base class is accessible.  */
-           /* Rather than inventing a public member, we use the implicit
-              public typedef created in the scope of every class.  */
-           decl = TYPE_FIELDS (base);
-           while (!DECL_SELF_REFERENCE_P (decl))
-             decl = TREE_CHAIN (decl);
-           while (ANON_AGGR_TYPE_P (t))
-             t = TYPE_CONTEXT (t);
-           if (!accessible_p (t, decl))
+           if (!(access & ba_quiet))
              {
-               if (!(access & ba_quiet))
-                 {
-                   error ("`%T' is an inaccessible base of `%T'", base, t);
-                   binfo = error_mark_node;
-                 }
-               else
-                 binfo = NULL_TREE;
-               bk = bk_inaccessible;
+               error ("`%T' is an inaccessible base of `%T'", base, t);
+               binfo = error_mark_node;
              }
+           else
+             binfo = NULL_TREE;
+           bk = bk_inaccessible;
          }
        break;
       }
index 354fa81af2e77f431d9c6198fbeee7192a47c089..1e703c101646b20c76e72f39b3697311acd2f7b0 100644 (file)
@@ -1,5 +1,8 @@
 2003-07-23  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/11645
+       * g++.dg/inherit/access4.C: New test.
+
        PR c++/11517
        * g++.dg/expr/cond2.C: New test.
        
diff --git a/gcc/testsuite/g++.dg/inherit/access4.C b/gcc/testsuite/g++.dg/inherit/access4.C
new file mode 100644 (file)
index 0000000..33f991b
--- /dev/null
@@ -0,0 +1,8 @@
+struct Container { int Count(); };
+struct List : private Container {
+    using Container::Count;
+};
+struct INetContentTypeParameterList : private List { void Clear(); };
+void INetContentTypeParameterList::Clear() {
+    Count();//Calling non static but in a non-static method.
+}