Commit 7d5b8b11 by Mark Mitchell Committed by Mark Mitchell

re PR c++/4842 (-Woverloaded-virtual does not work)

	PR c++/4842
	* class.c (get_basefndecls): Take an IDENTIFIER_NODE, not a
	FUNCTION_DECL, as input.
	(mark_overriders): Remove.
	(warn_hidden): Rework for the new ABI.

From-SVN: r47458
parent 45aff996
2001-11-29 Mark Mitchell <mark@codesourcery.com> 2001-11-29 Mark Mitchell <mark@codesourcery.com>
PR c++/4842
* class.c (get_basefndecls): Take an IDENTIFIER_NODE, not a
FUNCTION_DECL, as input.
(mark_overriders): Remove.
(warn_hidden): Rework for the new ABI.
2001-11-29 Mark Mitchell <mark@codesourcery.com>
PR c++/3471 PR c++/3471
* call.c (convert_like_real): Do not build additional temporaries * call.c (convert_like_real): Do not build additional temporaries
for rvalues of class type. for rvalues of class type.
......
...@@ -120,7 +120,6 @@ static void finish_struct_bits PARAMS ((tree)); ...@@ -120,7 +120,6 @@ static void finish_struct_bits PARAMS ((tree));
static int alter_access PARAMS ((tree, tree, tree)); static int alter_access PARAMS ((tree, tree, tree));
static void handle_using_decl PARAMS ((tree, tree)); static void handle_using_decl PARAMS ((tree, tree));
static int strictly_overrides PARAMS ((tree, tree)); static int strictly_overrides PARAMS ((tree, tree));
static void mark_overriders PARAMS ((tree, tree));
static void check_for_override PARAMS ((tree, tree)); static void check_for_override PARAMS ((tree, tree));
static tree dfs_modify_vtables PARAMS ((tree, void *)); static tree dfs_modify_vtables PARAMS ((tree, void *));
static tree modify_all_vtables PARAMS ((tree, int *, tree)); static tree modify_all_vtables PARAMS ((tree, int *, tree));
...@@ -2686,59 +2685,37 @@ strictly_overrides (fndecl1, fndecl2) ...@@ -2686,59 +2685,37 @@ strictly_overrides (fndecl1, fndecl2)
&& kind != bk_same_type); && kind != bk_same_type);
} }
/* Get the base virtual function declarations in T that are either /* Get the base virtual function declarations in T that have the
overridden or hidden by FNDECL as a list. We set TREE_PURPOSE with indicated NAME. */
the overrider/hider. */
static tree static tree
get_basefndecls (fndecl, t) get_basefndecls (name, t)
tree fndecl, t; tree name, t;
{ {
tree methods = TYPE_METHODS (t); tree methods;
tree base_fndecls = NULL_TREE; tree base_fndecls = NULL_TREE;
tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); int n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; int i;
while (methods) for (methods = TYPE_METHODS (t); methods; methods = TREE_CHAIN (methods))
{ if (TREE_CODE (methods) == FUNCTION_DECL
if (TREE_CODE (methods) == FUNCTION_DECL && DECL_VINDEX (methods) != NULL_TREE
&& DECL_VINDEX (methods) != NULL_TREE && DECL_NAME (methods) == name)
&& DECL_NAME (fndecl) == DECL_NAME (methods)) base_fndecls = tree_cons (NULL_TREE, methods, base_fndecls);
base_fndecls = tree_cons (fndecl, methods, base_fndecls);
methods = TREE_CHAIN (methods);
}
if (base_fndecls) if (base_fndecls)
return base_fndecls; return base_fndecls;
for (i = 0; i < n_baseclasses; i++) for (i = 0; i < n_baseclasses; i++)
{ {
tree base_binfo = TREE_VEC_ELT (binfos, i); tree basetype = TYPE_BINFO_BASETYPE (t, i);
tree basetype = BINFO_TYPE (base_binfo); base_fndecls = chainon (get_basefndecls (name, basetype),
base_fndecls = chainon (get_basefndecls (fndecl, basetype),
base_fndecls); base_fndecls);
} }
return base_fndecls; return base_fndecls;
} }
/* Mark the functions that have been hidden with their overriders.
Since we start out with all functions already marked with a hider,
no need to mark functions that are just hidden.
Subroutine of warn_hidden. */
static void
mark_overriders (fndecl, base_fndecls)
tree fndecl, base_fndecls;
{
for (; base_fndecls; base_fndecls = TREE_CHAIN (base_fndecls))
if (same_signature_p (fndecl, TREE_VALUE (base_fndecls)))
TREE_PURPOSE (base_fndecls) = fndecl;
}
/* If this declaration supersedes the declaration of /* If this declaration supersedes the declaration of
a method declared virtual in the base class, then a method declared virtual in the base class, then
mark this field as being virtual as well. */ mark this field as being virtual as well. */
...@@ -2786,57 +2763,59 @@ warn_hidden (t) ...@@ -2786,57 +2763,59 @@ warn_hidden (t)
/* We go through each separately named virtual function. */ /* We go through each separately named virtual function. */
for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); ++i) for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); ++i)
{ {
tree fns = TREE_VEC_ELT (method_vec, i); tree fns;
tree fndecl = NULL_TREE; tree name;
tree fndecl;
tree base_fndecls = NULL_TREE; tree base_fndecls;
tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); int j;
int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
/* All functions in this slot in the CLASSTYPE_METHOD_VEC will
/* First see if we have any virtual functions in this batch. */ have the same name. Figure out what name that is. */
for (; fns; fns = OVL_NEXT (fns)) name = DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i)));
/* There are no possibly hidden functions yet. */
base_fndecls = NULL_TREE;
/* Iterate through all of the base classes looking for possibly
hidden functions. */
for (j = 0; j < CLASSTYPE_N_BASECLASSES (t); j++)
{ {
fndecl = OVL_CURRENT (fns); tree basetype = TYPE_BINFO_BASETYPE (t, j);
if (DECL_VINDEX (fndecl)) base_fndecls = chainon (get_basefndecls (name, basetype),
break; base_fndecls);
} }
if (fns == NULL_TREE) /* If there are no functions to hide, continue. */
if (!base_fndecls)
continue; continue;
/* First we get a list of all possible functions that might be /* Remove any overridden functions. */
hidden from each base class. */ for (fns = TREE_VEC_ELT (method_vec, i); fns; fns = OVL_NEXT (fns))
for (i = 0; i < n_baseclasses; i++)
{ {
tree base_binfo = TREE_VEC_ELT (binfos, i); fndecl = OVL_CURRENT (fns);
tree basetype = BINFO_TYPE (base_binfo); if (DECL_VINDEX (fndecl))
{
base_fndecls = chainon (get_basefndecls (fndecl, basetype), tree *prev = &base_fndecls;
base_fndecls);
while (*prev)
/* If the method from the base class has the same
signature as the method from the derived class, it
has been overridden. */
if (same_signature_p (fndecl, TREE_VALUE (*prev)))
*prev = TREE_CHAIN (*prev);
else
prev = &TREE_CHAIN (*prev);
}
} }
fns = OVL_NEXT (fns);
/* ...then mark up all the base functions with overriders, preferring
overriders to hiders. */
if (base_fndecls)
for (; fns; fns = OVL_NEXT (fns))
{
fndecl = OVL_CURRENT (fns);
if (DECL_VINDEX (fndecl))
mark_overriders (fndecl, base_fndecls);
}
/* Now give a warning for all base functions without overriders, /* Now give a warning for all base functions without overriders,
as they are hidden. */ as they are hidden. */
for (; base_fndecls; base_fndecls = TREE_CHAIN (base_fndecls)) while (base_fndecls)
if (!same_signature_p (TREE_PURPOSE (base_fndecls), {
TREE_VALUE (base_fndecls))) /* Here we know it is a hider, and no overrider exists. */
{ cp_warning_at ("`%D' was hidden", TREE_VALUE (base_fndecls));
/* Here we know it is a hider, and no overrider exists. */ cp_warning_at (" by `%D'",
cp_warning_at ("`%D' was hidden", TREE_VALUE (base_fndecls)); OVL_CURRENT (TREE_VEC_ELT (method_vec, i)));
cp_warning_at (" by `%D'", TREE_PURPOSE (base_fndecls)); base_fndecls = TREE_CHAIN (base_fndecls);
} }
} }
} }
......
// Special g++ Options: -Woverloaded-virtual
// Build don't link:
struct A {
virtual void f(); // WARNING - hidden
};
struct B: public A {
void f(int); // WARNING - by this
};
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