]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/10990 (Cannot convert with dynamic_cast<> to a private base class from...
authorMark Mitchell <mark@codesourcery.com>
Thu, 26 Jun 2003 00:07:52 +0000 (00:07 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Thu, 26 Jun 2003 00:07:52 +0000 (00:07 +0000)
PR c++/10990
* search.c (lookup_base_r): Rely on accessible_p, rather than
trying to emulate that logic here.

PR c++/10990
* g++.dg/rtti/dyncast1.C: New test.
* g++.dg/abi/mangle4.C: Correct base-specifier access.
* g++.dg/lookup/scoped1.C: Remove XFAIL.
* g++.old-deja/g++.martin/pmf1.C: Correct base-specifier access.

From-SVN: r68507

gcc/cp/ChangeLog
gcc/cp/search.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/abi/mangle4.C
gcc/testsuite/g++.dg/lookup/scoped1.C
gcc/testsuite/g++.dg/rtti/dyncast1.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.martin/pmf1.C

index d6244467df1dbe87bce2b317ec16456b20ec763a..1ad3dc1954f1b7654276f3673a80ddb5ba4aa95e 100644 (file)
@@ -1,5 +1,9 @@
 2003-06-25  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/10990
+       * search.c (lookup_base_r): Rely on accessible_p, rather than
+       trying to emulate that logic here.
+
        PR c++/10931
        * call.c (convert_like): Pass issue_conversion_warnings.
        (convert_like_with_context): Likewise.
index a853c208bdf586e5a2998e28ca6e30fc32344e8d..84df08088eec1d0db86aa493cf537489d7b3c8f0 100644 (file)
@@ -188,8 +188,6 @@ lookup_base_r (tree binfo, tree base, base_access access,
       found = bk_same_type;
       if (is_virtual)
        found = bk_via_virtual;
-      if (is_non_public)
-       found = bk_inaccessible;
       
       if (!*binfo_ptr)
        *binfo_ptr = binfo;
@@ -317,30 +315,62 @@ lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr)
   bk = lookup_base_r (t_binfo, base, access & ~ba_quiet,
                      0, 0, 0, &binfo);
 
-  switch (bk)
-    {
-    case bk_inaccessible:
-      binfo = NULL_TREE;
-      if (!(access & ba_quiet))
-       {
-         error ("`%T' is an inaccessible base of `%T'", base, t);
-         binfo = error_mark_node;
-       }
-      break;
-    case bk_ambig:
-      if (access != ba_any)
-       {
-         binfo = NULL_TREE;
-         if (!(access & ba_quiet))
-           {
-             error ("`%T' is an ambiguous base of `%T'", base, t);
-             binfo = error_mark_node;
-           }
-       }
-      break;
-    default:;
-    }
-  
+  /* Check that the base is unambiguous and accessible.  */
+  if (access != ba_any)
+    switch (bk)
+      {
+      case bk_not_base:
+       break;
+
+      case bk_ambig:
+       binfo = NULL_TREE;
+       if (!(access & ba_quiet))
+         {
+           error ("`%T' is an ambiguous base of `%T'", base, t);
+           binfo = error_mark_node;
+         }
+       break;
+
+      default:
+       if (access != 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))
+         {
+           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 (TREE_CODE (decl) != TYPE_DECL
+                  || !DECL_ARTIFICIAL (decl)
+                  || DECL_NAME (decl) != constructor_name (base))
+             decl = TREE_CHAIN (decl);
+           while (ANON_AGGR_TYPE_P (t))
+             t = TYPE_CONTEXT (t);
+           if (!accessible_p (t, decl))
+             {
+               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;
+             }
+         }
+       break;
+      }
+
   if (kind_ptr)
     *kind_ptr = bk;
   
@@ -788,7 +818,7 @@ dfs_accessible_p (tree binfo, void *data)
 }
 
 /* Returns nonzero if it is OK to access DECL through an object
-   indiated by BINFO in the context of DERIVED.  */
+   indicated by BINFO in the context of DERIVED.  */
 
 static int
 protected_accessible_p (tree decl, tree derived, tree binfo)
index 8ae01588818711def0fc25c5294822042ae227d8..c593d4e646d7cf27b05289a0dc63f360283f52b5 100644 (file)
@@ -1,5 +1,11 @@
 2003-06-25  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/10990
+       * g++.dg/rtti/dyncast1.C: New test.
+       * g++.dg/abi/mangle4.C: Correct base-specifier access.
+       * g++.dg/lookup/scoped1.C: Remove XFAIL.
+       * g++.old-deja/g++.martin/pmf1.C: Correct base-specifier access.
+
        PR c++/10931
        * g++.dg/expr/static_cast1.C: New test.
        
index e0981273b2e94484fb42625f2d613a84ad9d36cb..ec65654e8e2145fc0d4db32f885386f3a3715f57 100644 (file)
@@ -2,7 +2,7 @@
 // { dg-do compile }
 
 class A {};
-class B : A {};
+class B : public A {};
 
 template<const A* a> class C {};
 template<const B* b> class D {};
index fc6c4b3c2691182d821189b0ad18508dfbd087b0..f1d3f403ea2a0244ced9d193e58942e3c9492c5d 100644 (file)
@@ -17,6 +17,6 @@ struct C: public B
     ::A::i1 = 1;
     ::A::i2 = 1;               // { dg-error "(access)|(context)" "" }
     ::A::f1 ();
-    ::A::f2 ();                        // { dg-error "access" "" { xfail *-*-* } }
+    ::A::f2 ();                        // { dg-error "" }
   }
 };
diff --git a/gcc/testsuite/g++.dg/rtti/dyncast1.C b/gcc/testsuite/g++.dg/rtti/dyncast1.C
new file mode 100644 (file)
index 0000000..204b446
--- /dev/null
@@ -0,0 +1,23 @@
+class JunkBase
+{
+public:
+    virtual void DoSomething( void ) = 0;
+protected:
+    virtual ~JunkBase( void ) {};
+    JunkBase( void ) {}
+};
+
+class Junk : protected JunkBase
+{
+public:
+    Junk( void ) : JunkBase() {}
+    virtual ~Junk( void ) {}
+protected:
+    inline JunkBase * AsBase( void )
+    { return dynamic_cast< JunkBase * >( this ); }
+    virtual void DoSomething( void ) { }
+};
+
+
+
+
index 2b5aa6489149ed47c3255c4500f48c58ecb71c00..108754b28df3f4d2b69ff65f1af04681da694d5d 100644 (file)
@@ -5,7 +5,7 @@
 
 struct B{};
 
-struct D:B{
+struct D: public B{
   virtual void foo();
 };