re PR c++/11645 (Failure to deal with using and private inheritance)
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. From-SVN: r69724
This commit is contained in:
parent
ff89cb01b7
commit
bd16cb258e
|
@ -1,5 +1,11 @@
|
|||
2003-07-23 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
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.
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
2003-07-23 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/11645
|
||||
* g++.dg/inherit/access4.C: New test.
|
||||
|
||||
PR c++/11517
|
||||
* g++.dg/expr/cond2.C: New test.
|
||||
|
||||
|
|
|
@ -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.
|
||||
}
|
Loading…
Reference in New Issue