aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>2003-08-23 13:02:17 +0000
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>2003-08-23 13:02:17 +0000
commita653d067f7084ce815c5e1a593eef7e5639564d2 (patch)
treed0952b4220f2626a3bb10135e5bd3d812fa871c2
parent19db77cefec38a1a0a3eb69007f01e8a1c108d5d (diff)
downloadgcc-a653d067f7084ce815c5e1a593eef7e5639564d2.zip
gcc-a653d067f7084ce815c5e1a593eef7e5639564d2.tar.gz
gcc-a653d067f7084ce815c5e1a593eef7e5639564d2.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/search.c44
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/parse/access6.C24
4 files changed, 61 insertions, 21 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ad2cdbc..5ae0891 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,14 @@
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
* friend.c (add_friend): Add complain parameter.
(make_friend_class): Likewise.
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index c646375..29e6172 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 c25f750..0432daf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
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
* g++.dg/template/friend22.C: New test.
* g++.dg/template/friend23.C: Likewise.
diff --git a/gcc/testsuite/g++.dg/parse/access6.C b/gcc/testsuite/g++.dg/parse/access6.C
new file mode 100644
index 0000000..33d5090
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/access6.C
@@ -0,0 +1,24 @@
+// { 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" }
+}