From 3a47db1ed1a9176b40509cefb5b24e6699b8b5a2 Mon Sep 17 00:00:00 2001 From: mmitchel Date: Wed, 23 Jul 2003 21:28:24 +0000 Subject: [PATCH] PR c++/11645 * cp-tree.h (accessible_base_p): Declare. * call.c (build_over_call): Use it. * search.c (accessible_base_p): New function, split out from ... (lookup_base): ... here. PR c++/11645 * g++.dg/inherit/access4.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@69724 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 6 ++++ gcc/cp/call.c | 7 ++++- gcc/cp/cp-tree.h | 1 + gcc/cp/search.c | 55 +++++++++++++++++++--------------- gcc/testsuite/ChangeLog | 3 ++ gcc/testsuite/g++.dg/inherit/access4.C | 8 +++++ 6 files changed, 55 insertions(+), 25 deletions(-) create mode 100644 gcc/testsuite/g++.dg/inherit/access4.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1ef39bff248..3314b35c158 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2003-07-23 Mark Mitchell + PR c++/11645 + * cp-tree.h (accessible_base_p): Declare. + * call.c (build_over_call): Use it. + * search.c (accessible_base_p): New function, split out from ... + (lookup_base): ... here. + PR c++/11517 * call.c (build_conditional_expr): Use perform_implicit_conversion and error_operand_p. Robustify. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index dddd7b80866..11e8d2e0cab 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4414,12 +4414,17 @@ build_over_call (struct z_candidate *cand, int flags) TREE_VALUE (arg), cand->conversion_path, 1); + /* Check that the base class is accessible. */ + if (!accessible_base_p (TREE_TYPE (argtype), + BINFO_TYPE (cand->conversion_path))) + error ("`%T' is not an accessible base of `%T'", + BINFO_TYPE (cand->conversion_path), + TREE_TYPE (argtype)); /* If fn was found by a using declaration, the conversion path will be to the derived class, not the base declaring fn. We must convert from derived to base. */ base_binfo = lookup_base (TREE_TYPE (TREE_TYPE (converted_arg)), TREE_TYPE (parmtype), ba_ignore, NULL); - converted_arg = build_base_path (PLUS_EXPR, converted_arg, base_binfo, 1); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index b4667527287..15bcea07eee 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4025,6 +4025,7 @@ extern void emit_support_tinfos (void); extern bool emit_tinfo_decl (tree); /* in search.c */ +extern bool accessible_base_p (tree, tree); extern tree lookup_base (tree, tree, base_access, base_kind *); extern int types_overlap_p (tree, tree); extern tree get_vbase (tree, tree); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 10b52164cd0..3f8e2daf8a8 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -231,6 +231,28 @@ lookup_base_r (tree binfo, tree base, base_access access, return found; } +/* Returns true if type BASE is accessible in T. (BASE is known to be + a base class of T.) */ + +bool +accessible_base_p (tree t, tree 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 (!DECL_SELF_REFERENCE_P (decl)) + decl = TREE_CHAIN (decl); + while (ANON_AGGR_TYPE_P (t)) + t = TYPE_CONTEXT (t); + return accessible_p (t, decl); +} + /* Lookup BASE in the hierarchy dominated by T. Do access checking as ACCESS specifies. Return the binfo we discover. If KIND_PTR is non-NULL, fill with information about what kind of base we @@ -287,39 +309,24 @@ lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr) break; default: - if (access != ba_ignore + if ((access & ~ba_quiet) != 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)) + && COMPLETE_TYPE_P (base) + && !accessible_base_p (t, 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 (!DECL_SELF_REFERENCE_P (decl)) - decl = TREE_CHAIN (decl); - while (ANON_AGGR_TYPE_P (t)) - t = TYPE_CONTEXT (t); - if (!accessible_p (t, decl)) + if (!(access & ba_quiet)) { - 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; + error ("`%T' is an inaccessible base of `%T'", base, t); + binfo = error_mark_node; } + else + binfo = NULL_TREE; + bk = bk_inaccessible; } break; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 354fa81af2e..1e703c10164 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2003-07-23 Mark Mitchell + PR c++/11645 + * g++.dg/inherit/access4.C: New test. + PR c++/11517 * g++.dg/expr/cond2.C: New test. diff --git a/gcc/testsuite/g++.dg/inherit/access4.C b/gcc/testsuite/g++.dg/inherit/access4.C new file mode 100644 index 00000000000..33f991b666f --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/access4.C @@ -0,0 +1,8 @@ +struct Container { int Count(); }; +struct List : private Container { + using Container::Count; +}; +struct INetContentTypeParameterList : private List { void Clear(); }; +void INetContentTypeParameterList::Clear() { + Count();//Calling non static but in a non-static method. +} -- 2.11.4.GIT