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>
|
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
|
PR c++/11517
|
||||||
* call.c (build_conditional_expr): Use perform_implicit_conversion
|
* call.c (build_conditional_expr): Use perform_implicit_conversion
|
||||||
and error_operand_p. Robustify.
|
and error_operand_p. Robustify.
|
||||||
|
|
|
@ -4414,12 +4414,17 @@ build_over_call (struct z_candidate *cand, int flags)
|
||||||
TREE_VALUE (arg),
|
TREE_VALUE (arg),
|
||||||
cand->conversion_path,
|
cand->conversion_path,
|
||||||
1);
|
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
|
/* If fn was found by a using declaration, the conversion path
|
||||||
will be to the derived class, not the base declaring fn. We
|
will be to the derived class, not the base declaring fn. We
|
||||||
must convert from derived to base. */
|
must convert from derived to base. */
|
||||||
base_binfo = lookup_base (TREE_TYPE (TREE_TYPE (converted_arg)),
|
base_binfo = lookup_base (TREE_TYPE (TREE_TYPE (converted_arg)),
|
||||||
TREE_TYPE (parmtype), ba_ignore, NULL);
|
TREE_TYPE (parmtype), ba_ignore, NULL);
|
||||||
|
|
||||||
converted_arg = build_base_path (PLUS_EXPR, converted_arg,
|
converted_arg = build_base_path (PLUS_EXPR, converted_arg,
|
||||||
base_binfo, 1);
|
base_binfo, 1);
|
||||||
|
|
||||||
|
|
|
@ -4025,6 +4025,7 @@ extern void emit_support_tinfos (void);
|
||||||
extern bool emit_tinfo_decl (tree);
|
extern bool emit_tinfo_decl (tree);
|
||||||
|
|
||||||
/* in search.c */
|
/* in search.c */
|
||||||
|
extern bool accessible_base_p (tree, tree);
|
||||||
extern tree lookup_base (tree, tree, base_access, base_kind *);
|
extern tree lookup_base (tree, tree, base_access, base_kind *);
|
||||||
extern int types_overlap_p (tree, tree);
|
extern int types_overlap_p (tree, tree);
|
||||||
extern tree get_vbase (tree, tree);
|
extern tree get_vbase (tree, tree);
|
||||||
|
|
|
@ -231,6 +231,28 @@ lookup_base_r (tree binfo, tree base, base_access access,
|
||||||
return found;
|
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
|
/* Lookup BASE in the hierarchy dominated by T. Do access checking as
|
||||||
ACCESS specifies. Return the binfo we discover. If KIND_PTR is
|
ACCESS specifies. Return the binfo we discover. If KIND_PTR is
|
||||||
non-NULL, fill with information about what kind of base we
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (access != ba_ignore
|
if ((access & ~ba_quiet) != ba_ignore
|
||||||
/* If BASE is incomplete, then BASE and TYPE are probably
|
/* If BASE is incomplete, then BASE and TYPE are probably
|
||||||
the same, in which case BASE is accessible. If they
|
the same, in which case BASE is accessible. If they
|
||||||
are not the same, then TYPE is invalid. In that case,
|
are not the same, then TYPE is invalid. In that case,
|
||||||
there's no need to issue another error here, and
|
there's no need to issue another error here, and
|
||||||
there's no implicit typedef to use in the code that
|
there's no implicit typedef to use in the code that
|
||||||
follows, so we skip the check. */
|
follows, so we skip the check. */
|
||||||
&& COMPLETE_TYPE_P (base))
|
&& COMPLETE_TYPE_P (base)
|
||||||
|
&& !accessible_base_p (t, base))
|
||||||
{
|
{
|
||||||
tree decl;
|
if (!(access & ba_quiet))
|
||||||
|
|
||||||
/* [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))
|
error ("`%T' is an inaccessible base of `%T'", base, t);
|
||||||
{
|
binfo = error_mark_node;
|
||||||
error ("`%T' is an inaccessible base of `%T'", base, t);
|
|
||||||
binfo = error_mark_node;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
binfo = NULL_TREE;
|
|
||||||
bk = bk_inaccessible;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
binfo = NULL_TREE;
|
||||||
|
bk = bk_inaccessible;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
2003-07-23 Mark Mitchell <mark@codesourcery.com>
|
2003-07-23 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
|
||||||
|
PR c++/11645
|
||||||
|
* g++.dg/inherit/access4.C: New test.
|
||||||
|
|
||||||
PR c++/11517
|
PR c++/11517
|
||||||
* g++.dg/expr/cond2.C: New test.
|
* 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