From: Mark Mitchell Date: Thu, 26 Jun 2003 00:07:52 +0000 (+0000) Subject: re PR c++/10990 (Cannot convert with dynamic_cast<> to a private base class from... X-Git-Tag: releases/gcc-3.4.0~5471 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e80706c4a45eb63d7fd52f6bb0a2ccf28f2eba75;p=thirdparty%2Fgcc.git re PR c++/10990 (Cannot convert with dynamic_cast<> to a private base class from within a member function) 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d6244467df1d..1ad3dc1954f1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2003-06-25 Mark Mitchell + 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. diff --git a/gcc/cp/search.c b/gcc/cp/search.c index a853c208bdf5..84df08088eec 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8ae015888187..c593d4e646d7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2003-06-25 Mark Mitchell + 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. diff --git a/gcc/testsuite/g++.dg/abi/mangle4.C b/gcc/testsuite/g++.dg/abi/mangle4.C index e0981273b2e9..ec65654e8e21 100644 --- a/gcc/testsuite/g++.dg/abi/mangle4.C +++ b/gcc/testsuite/g++.dg/abi/mangle4.C @@ -2,7 +2,7 @@ // { dg-do compile } class A {}; -class B : A {}; +class B : public A {}; template class C {}; template class D {}; diff --git a/gcc/testsuite/g++.dg/lookup/scoped1.C b/gcc/testsuite/g++.dg/lookup/scoped1.C index fc6c4b3c2691..f1d3f403ea2a 100644 --- a/gcc/testsuite/g++.dg/lookup/scoped1.C +++ b/gcc/testsuite/g++.dg/lookup/scoped1.C @@ -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 index 000000000000..204b4462f930 --- /dev/null +++ b/gcc/testsuite/g++.dg/rtti/dyncast1.C @@ -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 ) { } +}; + + + + diff --git a/gcc/testsuite/g++.old-deja/g++.martin/pmf1.C b/gcc/testsuite/g++.old-deja/g++.martin/pmf1.C index 2b5aa6489149..108754b28df3 100644 --- a/gcc/testsuite/g++.old-deja/g++.martin/pmf1.C +++ b/gcc/testsuite/g++.old-deja/g++.martin/pmf1.C @@ -5,7 +5,7 @@ struct B{}; -struct D:B{ +struct D: public B{ virtual void foo(); };