Commit 940ab2e0 by Nathan Sidwell Committed by Nathan Sidwell

class.c (warn_hidden): Don't barf on non-functions.

	* class.c (warn_hidden): Don't barf on non-functions.
	* decl2.c (check_classfn): Likewise.  Check template match earlier.

From-SVN: r251795
parent 1887fb46
2017-09-06 Nathan Sidwell <nathan@acm.org>
* class.c (warn_hidden): Don't barf on non-functions.
* decl2.c (check_classfn): Likewise. Check template match earlier.
* name-lookup.c (count_fields): Rename to ...
(count_class_fields): ... here. Take a class, don't count
NULL-named fields.
......
......@@ -2818,63 +2818,64 @@ check_for_override (tree decl, tree ctype)
static void
warn_hidden (tree t)
{
vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (t);
tree fns;
if (vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (t))
for (unsigned ix = method_vec->length (); ix--;)
{
tree fns = (*method_vec)[ix];
/* We go through each separately named virtual function. */
for (int i = 0; vec_safe_iterate (method_vec, i, &fns); ++i)
{
tree name = OVL_NAME (fns);
auto_vec<tree, 20> base_fndecls;
tree base_binfo;
tree binfo;
int j;
if (!OVL_P (fns))
continue;
/* Iterate through all of the base classes looking for possibly
hidden functions. */
for (binfo = TYPE_BINFO (t), j = 0;
BINFO_BASE_ITERATE (binfo, j, base_binfo); j++)
{
tree basetype = BINFO_TYPE (base_binfo);
get_basefndecls (name, basetype, &base_fndecls);
}
tree name = OVL_NAME (fns);
auto_vec<tree, 20> base_fndecls;
tree base_binfo;
tree binfo;
unsigned j;
/* If there are no functions to hide, continue. */
if (base_fndecls.is_empty ())
continue;
/* Iterate through all of the base classes looking for possibly
hidden functions. */
for (binfo = TYPE_BINFO (t), j = 0;
BINFO_BASE_ITERATE (binfo, j, base_binfo); j++)
{
tree basetype = BINFO_TYPE (base_binfo);
get_basefndecls (name, basetype, &base_fndecls);
}
/* Remove any overridden functions. */
for (ovl_iterator iter (fns); iter; ++iter)
{
tree fndecl = *iter;
if (TREE_CODE (fndecl) == FUNCTION_DECL
&& DECL_VINDEX (fndecl))
{
/* If the method from the base class has the same
signature as the method from the derived class, it
has been overridden. */
for (size_t k = 0; k < base_fndecls.length (); k++)
if (base_fndecls[k]
&& same_signature_p (fndecl, base_fndecls[k]))
base_fndecls[k] = NULL_TREE;
}
}
/* If there are no functions to hide, continue. */
if (base_fndecls.is_empty ())
continue;
/* Now give a warning for all base functions without overriders,
as they are hidden. */
size_t k;
tree base_fndecl;
FOR_EACH_VEC_ELT (base_fndecls, k, base_fndecl)
if (base_fndecl)
/* Remove any overridden functions. */
for (ovl_iterator iter (fns); iter; ++iter)
{
/* Here we know it is a hider, and no overrider exists. */
warning_at (location_of (base_fndecl),
OPT_Woverloaded_virtual,
"%qD was hidden", base_fndecl);
warning_at (location_of (fns),
OPT_Woverloaded_virtual, " by %qD", fns);
tree fndecl = *iter;
if (TREE_CODE (fndecl) == FUNCTION_DECL
&& DECL_VINDEX (fndecl))
{
/* If the method from the base class has the same
signature as the method from the derived class, it
has been overridden. */
for (size_t k = 0; k < base_fndecls.length (); k++)
if (base_fndecls[k]
&& same_signature_p (fndecl, base_fndecls[k]))
base_fndecls[k] = NULL_TREE;
}
}
}
/* Now give a warning for all base functions without overriders,
as they are hidden. */
tree base_fndecl;
FOR_EACH_VEC_ELT (base_fndecls, j, base_fndecl)
if (base_fndecl)
{
/* Here we know it is a hider, and no overrider exists. */
warning_at (location_of (base_fndecl),
OPT_Woverloaded_virtual,
"%qD was hidden", base_fndecl);
warning_at (location_of (fns),
OPT_Woverloaded_virtual, " by %qD", fns);
}
}
}
/* Recursive helper for finish_struct_anon. */
......@@ -6981,7 +6982,7 @@ unreverse_member_declarations (tree t)
/* For the TYPE_FIELDS, only the non TYPE_DECLs are in reverse
order, so we can't just use nreverse. Due to stat_hack
chicanery in finish_member_declarations. */
chicanery in finish_member_declaration. */
prev = NULL_TREE;
for (x = TYPE_FIELDS (t);
x && TREE_CODE (x) != TYPE_DECL;
......
......@@ -611,6 +611,15 @@ check_classfn (tree ctype, tree function, tree template_parms)
for (ovl_iterator iter (fns); !matched && iter; ++iter)
{
tree fndecl = *iter;
/* A member template definition only matches a member template
declaration. */
if (is_template != (TREE_CODE (fndecl) == TEMPLATE_DECL))
continue;
if (!DECL_DECLARES_FUNCTION_P (fndecl))
continue;
tree p1 = TYPE_ARG_TYPES (TREE_TYPE (function));
tree p2 = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
......@@ -625,11 +634,6 @@ check_classfn (tree ctype, tree function, tree template_parms)
&& TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
p1 = TREE_CHAIN (p1);
/* A member template definition only matches a member template
declaration. */
if (is_template != (TREE_CODE (fndecl) == TEMPLATE_DECL))
continue;
/* ref-qualifier or absence of same must match. */
if (type_memfn_rqual (TREE_TYPE (function))
!= type_memfn_rqual (TREE_TYPE (fndecl)))
......
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