diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/search.c | 84 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle4.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lookup/scoped1.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/rtti/dyncast1.C | 23 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.martin/pmf1.C | 2 |
7 files changed, 93 insertions, 30 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d624446..1ad3dc1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/search.c b/gcc/cp/search.c index a853c20..84df080 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 8ae0158..c593d4e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/g++.dg/abi/mangle4.C b/gcc/testsuite/g++.dg/abi/mangle4.C index e098127..ec65654 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<const A* a> class C {}; template<const B* b> class D {}; diff --git a/gcc/testsuite/g++.dg/lookup/scoped1.C b/gcc/testsuite/g++.dg/lookup/scoped1.C index fc6c4b3..f1d3f40 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 0000000..204b446 --- /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 2b5aa64..108754b 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(); }; |