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
This commit is contained in:
parent
45aff9968e
commit
7d5b8b116e
@ -1,3 +1,11 @@
|
||||
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
|
||||
|
137
gcc/cp/class.c
137
gcc/cp/class.c
@ -120,7 +120,6 @@ static void finish_struct_bits PARAMS ((tree));
|
||||
static int alter_access PARAMS ((tree, tree, tree));
|
||||
static void handle_using_decl 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 tree dfs_modify_vtables PARAMS ((tree, void *));
|
||||
static tree modify_all_vtables PARAMS ((tree, int *, tree));
|
||||
@ -2686,59 +2685,37 @@ strictly_overrides (fndecl1, fndecl2)
|
||||
&& kind != bk_same_type);
|
||||
}
|
||||
|
||||
/* Get the base virtual function declarations in T that are either
|
||||
overridden or hidden by FNDECL as a list. We set TREE_PURPOSE with
|
||||
the overrider/hider. */
|
||||
/* Get the base virtual function declarations in T that have the
|
||||
indicated NAME. */
|
||||
|
||||
static tree
|
||||
get_basefndecls (fndecl, t)
|
||||
tree fndecl, t;
|
||||
get_basefndecls (name, t)
|
||||
tree name, t;
|
||||
{
|
||||
tree methods = TYPE_METHODS (t);
|
||||
tree methods;
|
||||
tree base_fndecls = NULL_TREE;
|
||||
tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
|
||||
int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
|
||||
int n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
|
||||
int i;
|
||||
|
||||
while (methods)
|
||||
{
|
||||
if (TREE_CODE (methods) == FUNCTION_DECL
|
||||
&& DECL_VINDEX (methods) != NULL_TREE
|
||||
&& DECL_NAME (fndecl) == DECL_NAME (methods))
|
||||
base_fndecls = tree_cons (fndecl, methods, base_fndecls);
|
||||
|
||||
methods = TREE_CHAIN (methods);
|
||||
}
|
||||
for (methods = TYPE_METHODS (t); methods; methods = TREE_CHAIN (methods))
|
||||
if (TREE_CODE (methods) == FUNCTION_DECL
|
||||
&& DECL_VINDEX (methods) != NULL_TREE
|
||||
&& DECL_NAME (methods) == name)
|
||||
base_fndecls = tree_cons (NULL_TREE, methods, base_fndecls);
|
||||
|
||||
if (base_fndecls)
|
||||
return base_fndecls;
|
||||
|
||||
for (i = 0; i < n_baseclasses; i++)
|
||||
{
|
||||
tree base_binfo = TREE_VEC_ELT (binfos, i);
|
||||
tree basetype = BINFO_TYPE (base_binfo);
|
||||
|
||||
base_fndecls = chainon (get_basefndecls (fndecl, basetype),
|
||||
tree basetype = TYPE_BINFO_BASETYPE (t, i);
|
||||
base_fndecls = chainon (get_basefndecls (name, basetype),
|
||||
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
|
||||
a method declared virtual in the base class, then
|
||||
mark this field as being virtual as well. */
|
||||
@ -2786,57 +2763,59 @@ warn_hidden (t)
|
||||
/* We go through each separately named virtual function. */
|
||||
for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); ++i)
|
||||
{
|
||||
tree fns = TREE_VEC_ELT (method_vec, i);
|
||||
tree fndecl = NULL_TREE;
|
||||
tree fns;
|
||||
tree name;
|
||||
tree fndecl;
|
||||
tree base_fndecls;
|
||||
int j;
|
||||
|
||||
tree base_fndecls = NULL_TREE;
|
||||
tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
|
||||
int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
|
||||
|
||||
/* First see if we have any virtual functions in this batch. */
|
||||
for (; fns; fns = OVL_NEXT (fns))
|
||||
/* All functions in this slot in the CLASSTYPE_METHOD_VEC will
|
||||
have the same name. Figure out what name that is. */
|
||||
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);
|
||||
if (DECL_VINDEX (fndecl))
|
||||
break;
|
||||
}
|
||||
|
||||
if (fns == NULL_TREE)
|
||||
continue;
|
||||
|
||||
/* First we get a list of all possible functions that might be
|
||||
hidden from each base class. */
|
||||
for (i = 0; i < n_baseclasses; i++)
|
||||
{
|
||||
tree base_binfo = TREE_VEC_ELT (binfos, i);
|
||||
tree basetype = BINFO_TYPE (base_binfo);
|
||||
|
||||
base_fndecls = chainon (get_basefndecls (fndecl, basetype),
|
||||
tree basetype = TYPE_BINFO_BASETYPE (t, j);
|
||||
base_fndecls = chainon (get_basefndecls (name, basetype),
|
||||
base_fndecls);
|
||||
}
|
||||
|
||||
fns = OVL_NEXT (fns);
|
||||
/* If there are no functions to hide, continue. */
|
||||
if (!base_fndecls)
|
||||
continue;
|
||||
|
||||
/* ...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);
|
||||
}
|
||||
/* Remove any overridden functions. */
|
||||
for (fns = TREE_VEC_ELT (method_vec, i); fns; fns = OVL_NEXT (fns))
|
||||
{
|
||||
fndecl = OVL_CURRENT (fns);
|
||||
if (DECL_VINDEX (fndecl))
|
||||
{
|
||||
tree *prev = &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);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now give a warning for all base functions without overriders,
|
||||
as they are hidden. */
|
||||
for (; base_fndecls; base_fndecls = TREE_CHAIN (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));
|
||||
cp_warning_at (" by `%D'", TREE_PURPOSE (base_fndecls));
|
||||
}
|
||||
while (base_fndecls)
|
||||
{
|
||||
/* Here we know it is a hider, and no overrider exists. */
|
||||
cp_warning_at ("`%D' was hidden", TREE_VALUE (base_fndecls));
|
||||
cp_warning_at (" by `%D'",
|
||||
OVL_CURRENT (TREE_VEC_ELT (method_vec, i)));
|
||||
base_fndecls = TREE_CHAIN (base_fndecls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
10
gcc/testsuite/g++.old-deja/g++.warn/virt1.C
Normal file
10
gcc/testsuite/g++.old-deja/g++.warn/virt1.C
Normal file
@ -0,0 +1,10 @@
|
||||
// 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
|
||||
};
|
Loading…
Reference in New Issue
Block a user