From a653d067f7084ce815c5e1a593eef7e5639564d2 Mon Sep 17 00:00:00 2001 From: Kriang Lerdsuwanakij Date: Sat, 23 Aug 2003 13:02:17 +0000 Subject: [PATCH] re PR c++/3765 (member using declaration can't change access from public) PR c++/3765 * search.c (dfs_access_in_type): Fix typo in comment. (dfs_accessible_queue_p): Likewise. (dfs_accessible_p): Only terminate when a friend is found. (accessible_p): Return immediately if access_in_type allows access. * g++.dg/parse/access6.C: New test. From-SVN: r70733 --- gcc/cp/ChangeLog | 9 ++++++ gcc/cp/search.c | 44 +++++++++++++++------------- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/parse/access6.C | 24 +++++++++++++++ 4 files changed, 61 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/access6.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ad2cdbc2387..5ae0891f7c1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2003-08-23 Kriang Lerdsuwanakij + + PR c++/3765 + * search.c (dfs_access_in_type): Fix typo in comment. + (dfs_accessible_queue_p): Likewise. + (dfs_accessible_p): Only terminate when a friend is found. + (accessible_p): Return immediately if access_in_type allows + access. + 2003-08-23 Kriang Lerdsuwanakij PR c++/641, c++/11876 diff --git a/gcc/cp/search.c b/gcc/cp/search.c index c6463751926..29e6172c325 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -625,7 +625,7 @@ dfs_access_in_type (tree binfo, void *data) if (context_for_name_lookup (decl) == type) { - /* If we have desceneded to the scope of DECL, just note the + /* If we have descended to the scope of DECL, just note the appropriate access. */ if (TREE_PRIVATE (decl)) access = ak_private; @@ -739,7 +739,7 @@ access_in_type (tree type, tree decl) return BINFO_ACCESS (binfo); } -/* Called from dfs_accessible_p via dfs_walk. */ +/* Called from accessible_p via dfs_walk. */ static tree dfs_accessible_queue_p (tree derived, int ix, void *data ATTRIBUTE_UNUSED) @@ -758,20 +758,17 @@ dfs_accessible_queue_p (tree derived, int ix, void *data ATTRIBUTE_UNUSED) return binfo; } -/* Called from dfs_accessible_p via dfs_walk. */ +/* Called from accessible_p via dfs_walk. */ static tree -dfs_accessible_p (tree binfo, void *data) +dfs_accessible_p (tree binfo, void *data ATTRIBUTE_UNUSED) { - int protected_ok = data != 0; access_kind access; BINFO_MARKED (binfo) = 1; access = BINFO_ACCESS (binfo); - if (access == ak_public || (access == ak_protected && protected_ok)) - return binfo; - else if (access != ak_none - && is_friend (BINFO_TYPE (binfo), current_scope ())) + if (access != ak_none + && is_friend (BINFO_TYPE (binfo), current_scope ())) return binfo; return NULL_TREE; @@ -898,6 +895,7 @@ accessible_p (tree type, tree decl) { tree binfo; tree t; + access_kind access; /* Nonzero if it's OK to access DECL if it has protected accessibility in TYPE. */ @@ -958,18 +956,22 @@ accessible_p (tree type, tree decl) /* Compute the accessibility of DECL in the class hierarchy dominated by type. */ - access_in_type (type, decl); - /* Walk the hierarchy again, looking for a base class that allows - access. */ - t = dfs_walk (binfo, dfs_accessible_p, - dfs_accessible_queue_p, - protected_ok ? &protected_ok : 0); - /* Clear any mark bits. Note that we have to walk the whole tree - here, since we have aborted the previous walk from some point - deep in the tree. */ - dfs_walk (binfo, dfs_unmark, 0, 0); - - return t != NULL_TREE; + access = access_in_type (type, decl); + if (access == ak_public + || (access == ak_protected && protected_ok)) + return 1; + else + { + /* Walk the hierarchy again, looking for a base class that allows + access. */ + t = dfs_walk (binfo, dfs_accessible_p, dfs_accessible_queue_p, 0); + /* Clear any mark bits. Note that we have to walk the whole tree + here, since we have aborted the previous walk from some point + deep in the tree. */ + dfs_walk (binfo, dfs_unmark, 0, 0); + + return t != NULL_TREE; + } } struct lookup_field_info { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c25f750b5b6..0432dafa6b5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-08-23 Kriang Lerdsuwanakij + + PR c++/3765 + * g++.dg/parse/access6.C: New test. + 2003-08-23 Kriang Lerdsuwanakij PR c++/641, c++/11876 diff --git a/gcc/testsuite/g++.dg/parse/access6.C b/gcc/testsuite/g++.dg/parse/access6.C new file mode 100644 index 00000000000..33d50905854 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/access6.C @@ -0,0 +1,24 @@ +// { dg-do compile } + +// Origin: David Baron + +// PR c++/3765: Changing access from public to private by member +// using declaration. + +class A +{ + public: + int foo() { return 1; } // { dg-error "inaccessible" } +}; + +class B : public A +{ + private: + using A::foo; +}; + +int main() +{ + B b; + return b.foo(); // { dg-error "this context" } +} -- 2.30.2