Commit a653d067 by Kriang Lerdsuwanakij Committed by Kriang Lerdsuwanakij

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
parent 19db77ce
2003-08-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> 2003-08-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
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 <lerdsuwa@users.sourceforge.net>
PR c++/641, c++/11876 PR c++/641, c++/11876
* friend.c (add_friend): Add complain parameter. * friend.c (add_friend): Add complain parameter.
(make_friend_class): Likewise. (make_friend_class): Likewise.
......
...@@ -625,7 +625,7 @@ dfs_access_in_type (tree binfo, void *data) ...@@ -625,7 +625,7 @@ dfs_access_in_type (tree binfo, void *data)
if (context_for_name_lookup (decl) == type) 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. */ appropriate access. */
if (TREE_PRIVATE (decl)) if (TREE_PRIVATE (decl))
access = ak_private; access = ak_private;
...@@ -739,7 +739,7 @@ access_in_type (tree type, tree decl) ...@@ -739,7 +739,7 @@ access_in_type (tree type, tree decl)
return BINFO_ACCESS (binfo); return BINFO_ACCESS (binfo);
} }
/* Called from dfs_accessible_p via dfs_walk. */ /* Called from accessible_p via dfs_walk. */
static tree static tree
dfs_accessible_queue_p (tree derived, int ix, void *data ATTRIBUTE_UNUSED) 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) ...@@ -758,20 +758,17 @@ dfs_accessible_queue_p (tree derived, int ix, void *data ATTRIBUTE_UNUSED)
return binfo; return binfo;
} }
/* Called from dfs_accessible_p via dfs_walk. */ /* Called from accessible_p via dfs_walk. */
static tree 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; access_kind access;
BINFO_MARKED (binfo) = 1; BINFO_MARKED (binfo) = 1;
access = BINFO_ACCESS (binfo); access = BINFO_ACCESS (binfo);
if (access == ak_public || (access == ak_protected && protected_ok)) if (access != ak_none
return binfo; && is_friend (BINFO_TYPE (binfo), current_scope ()))
else if (access != ak_none
&& is_friend (BINFO_TYPE (binfo), current_scope ()))
return binfo; return binfo;
return NULL_TREE; return NULL_TREE;
...@@ -898,6 +895,7 @@ accessible_p (tree type, tree decl) ...@@ -898,6 +895,7 @@ accessible_p (tree type, tree decl)
{ {
tree binfo; tree binfo;
tree t; tree t;
access_kind access;
/* Nonzero if it's OK to access DECL if it has protected /* Nonzero if it's OK to access DECL if it has protected
accessibility in TYPE. */ accessibility in TYPE. */
...@@ -958,18 +956,22 @@ accessible_p (tree type, tree decl) ...@@ -958,18 +956,22 @@ accessible_p (tree type, tree decl)
/* Compute the accessibility of DECL in the class hierarchy /* Compute the accessibility of DECL in the class hierarchy
dominated by type. */ dominated by type. */
access_in_type (type, decl); access = access_in_type (type, decl);
/* Walk the hierarchy again, looking for a base class that allows if (access == ak_public
access. */ || (access == ak_protected && protected_ok))
t = dfs_walk (binfo, dfs_accessible_p, return 1;
dfs_accessible_queue_p, else
protected_ok ? &protected_ok : 0); {
/* Clear any mark bits. Note that we have to walk the whole tree /* Walk the hierarchy again, looking for a base class that allows
here, since we have aborted the previous walk from some point access. */
deep in the tree. */ t = dfs_walk (binfo, dfs_accessible_p, dfs_accessible_queue_p, 0);
dfs_walk (binfo, dfs_unmark, 0, 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
return t != NULL_TREE; deep in the tree. */
dfs_walk (binfo, dfs_unmark, 0, 0);
return t != NULL_TREE;
}
} }
struct lookup_field_info { struct lookup_field_info {
......
2003-08-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> 2003-08-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/3765
* g++.dg/parse/access6.C: New test.
2003-08-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/641, c++/11876 PR c++/641, c++/11876
* g++.dg/template/friend22.C: New test. * g++.dg/template/friend22.C: New test.
* g++.dg/template/friend23.C: Likewise. * g++.dg/template/friend23.C: Likewise.
......
// { dg-do compile }
// Origin: David Baron <dbaron@fas.harvard.edu>
// 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" }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment