Revert "c++: Fix overeager Woverloaded-virtual with conversion operators [PR109918]"
This reverts commit 60163c8573
.
This commit is contained in:
parent
f0f11559d5
commit
a4eec6c712
8 changed files with 33 additions and 135 deletions
|
@ -3243,15 +3243,10 @@ warn_hidden (tree t)
|
|||
continue;
|
||||
|
||||
tree name = OVL_NAME (fns);
|
||||
size_t num_fns = 0; /* The number of fndecls in fns. */
|
||||
auto_vec<tree, 20> base_fndecls;
|
||||
tree base_binfo;
|
||||
tree binfo;
|
||||
unsigned j;
|
||||
hash_set<tree> overriden_base_fndecls;
|
||||
/* base_fndecls that are hidden but not overriden. The "value"
|
||||
contains the fndecl that hides the "key". */
|
||||
hash_map<tree, tree> hidden_base_fndecls;
|
||||
|
||||
if (IDENTIFIER_CDTOR_P (name))
|
||||
continue;
|
||||
|
@ -3269,63 +3264,47 @@ warn_hidden (tree t)
|
|||
if (base_fndecls.is_empty ())
|
||||
continue;
|
||||
|
||||
/* Find all the base_fndecls that are overridden, as well as those
|
||||
that are hidden, in T. */
|
||||
/* Remove any overridden functions. */
|
||||
bool seen_non_override = false;
|
||||
for (tree fndecl : ovl_range (fns))
|
||||
{
|
||||
fndecl = STRIP_TEMPLATE (fndecl);
|
||||
bool any_override = false;
|
||||
if (TREE_CODE (fndecl) == FUNCTION_DECL
|
||||
&& fndecl != conv_op_marker)
|
||||
&& DECL_VINDEX (fndecl))
|
||||
{
|
||||
num_fns++;
|
||||
tree fndecl_vindex = DECL_VINDEX (fndecl);
|
||||
/* If the method from the base class has the same DECL_VINDEX
|
||||
as the method from the derived, it has been overridden.
|
||||
Note that we can't move on after finding one match: fndecl
|
||||
might override multiple base fns. */
|
||||
/* If the method from the base class has the same
|
||||
signature as the method from the derived class, it
|
||||
has been overridden. Note that we can't move on
|
||||
after finding one match: fndecl might override
|
||||
multiple base fns. */
|
||||
for (size_t k = 0; k < base_fndecls.length (); k++)
|
||||
{
|
||||
if (!base_fndecls[k] || !DECL_VINDEX (base_fndecls[k]))
|
||||
continue;
|
||||
tree base_fndecl_vindex = DECL_VINDEX (base_fndecls[k]);
|
||||
if (fndecl_vindex
|
||||
&& !tree_int_cst_compare (fndecl_vindex,
|
||||
base_fndecl_vindex))
|
||||
overriden_base_fndecls.add (base_fndecls[k]);
|
||||
else if (IDENTIFIER_CONV_OP_P (name)
|
||||
&& (DECL_NAME (fndecl)
|
||||
!= DECL_NAME (base_fndecls[k])))
|
||||
/* If base_fndecl[k] and fndecl are conversion operators
|
||||
to different types, they're unrelated. */
|
||||
;
|
||||
else
|
||||
hidden_base_fndecls.put (base_fndecls[k], fndecl);
|
||||
}
|
||||
if (base_fndecls[k]
|
||||
&& same_signature_p (fndecl, base_fndecls[k]))
|
||||
{
|
||||
base_fndecls[k] = NULL_TREE;
|
||||
any_override = true;
|
||||
}
|
||||
}
|
||||
if (!any_override)
|
||||
seen_non_override = true;
|
||||
}
|
||||
|
||||
if (warn_overloaded_virtual == 1
|
||||
&& overriden_base_fndecls.elements () == num_fns)
|
||||
/* All the fns override a base virtual. */
|
||||
continue;
|
||||
if (!seen_non_override && warn_overloaded_virtual == 1)
|
||||
/* All the derived fns override base virtuals. */
|
||||
return;
|
||||
|
||||
/* Now give a warning for all hidden methods. Note that a method that
|
||||
is both in hidden_base_fndecls and overriden_base_fndecls is not
|
||||
hidden. */
|
||||
for (auto hidden_base_fndecl : hidden_base_fndecls)
|
||||
{
|
||||
tree hidden_fndecl = hidden_base_fndecl.first;
|
||||
tree hider = hidden_base_fndecl.second;
|
||||
if (!hidden_fndecl
|
||||
|| overriden_base_fndecls.contains (hidden_fndecl))
|
||||
continue;
|
||||
gcc_assert (hider);
|
||||
auto_diagnostic_group d;
|
||||
if (warning_at (location_of (hidden_fndecl),
|
||||
OPT_Woverloaded_virtual_,
|
||||
"%qD was hidden", hidden_fndecl))
|
||||
inform (location_of (hider), " by %qD", hider);
|
||||
}
|
||||
/* Now give a warning for all base functions without overriders,
|
||||
as they are hidden. */
|
||||
for (tree base_fndecl : base_fndecls)
|
||||
if (base_fndecl)
|
||||
{
|
||||
auto_diagnostic_group d;
|
||||
/* Here we know it is a hider, and no overrider exists. */
|
||||
if (warning_at (location_of (base_fndecl),
|
||||
OPT_Woverloaded_virtual_,
|
||||
"%qD was hidden", base_fndecl))
|
||||
inform (location_of (fns), " by %qD", fns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3397,8 +3397,7 @@ location_of (tree t)
|
|||
return input_location;
|
||||
}
|
||||
else if (TREE_CODE (t) == OVERLOAD)
|
||||
t = OVL_FIRST (t) != conv_op_marker ? OVL_FIRST (t)
|
||||
: OVL_FIRST (OVL_CHAIN (t));
|
||||
t = OVL_FIRST (t);
|
||||
|
||||
if (DECL_P (t))
|
||||
return DECL_SOURCE_LOCATION (t);
|
||||
|
|
|
@ -5,12 +5,10 @@ class Foo
|
|||
{
|
||||
public:
|
||||
virtual void f(int); // { dg-warning "hidden" }
|
||||
void g(int); // Not virtual, so no warning
|
||||
};
|
||||
|
||||
class Bar : public Foo
|
||||
{
|
||||
public:
|
||||
virtual void f(short); // { dg-message "by" }
|
||||
virtual void g(short);
|
||||
};
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
// PR c++/109918 - Exact PR testcase
|
||||
// { dg-do compile }
|
||||
// { dg-additional-options -Wall }
|
||||
|
||||
struct A {
|
||||
virtual operator int() { return 42; }
|
||||
virtual operator char() = 0;
|
||||
};
|
||||
|
||||
struct B : public A {
|
||||
operator char() { return 'A'; }
|
||||
};
|
|
@ -1,12 +0,0 @@
|
|||
// PR c++/109918 - PR testcase with -Woverloaded-virtual=2
|
||||
// { dg-do compile }
|
||||
// { dg-additional-options -Woverloaded-virtual=2 }
|
||||
|
||||
struct A {
|
||||
virtual operator int() { return 42; }
|
||||
virtual operator char() = 0;
|
||||
};
|
||||
|
||||
struct B : public A {
|
||||
operator char() { return 'A'; }
|
||||
};
|
|
@ -1,25 +0,0 @@
|
|||
// PR c++/109918 - Test different CV-quals
|
||||
// { dg-do compile }
|
||||
// { dg-additional-options -Woverloaded-virtual }
|
||||
|
||||
struct A {
|
||||
virtual operator char() { return 'a'; }
|
||||
virtual operator char() const { return 'b'; } // { dg-warning "was hidden" }
|
||||
virtual operator int() { return 42; }
|
||||
};
|
||||
|
||||
struct B : public A {
|
||||
operator char() { return 'A'; } // { dg-note "by" }
|
||||
operator int() { return 43; }
|
||||
};
|
||||
|
||||
struct AA {
|
||||
virtual char func(char) { return 'a'; }
|
||||
virtual char func(char) const { return 'b'; } // { dg-warning "was hidden" }
|
||||
virtual int func(int) { return 42; }
|
||||
};
|
||||
|
||||
struct BB : public AA {
|
||||
char func(char) { return 'A'; } // { dg-note "by" }
|
||||
int func(int) { return 43; }
|
||||
};
|
|
@ -1,15 +0,0 @@
|
|||
// Identified when investigating PR c++/109918: no warning was emitted due to
|
||||
// an incorrect early return in warn_hidden.
|
||||
// { dg-additional-options -Wall }
|
||||
|
||||
struct Foo
|
||||
{
|
||||
virtual void f(int); // { dg-warning "hidden" }
|
||||
virtual void g() {}
|
||||
};
|
||||
|
||||
struct Bar : Foo
|
||||
{
|
||||
virtual void f(short); // { dg-message "by" }
|
||||
virtual void g() {}
|
||||
};
|
|
@ -1,14 +0,0 @@
|
|||
// PR c++/109918: Non virtual overloads in derived classes that don't override
|
||||
// anything shouldn't cause warnings, even at -Woverloaded-virtual=2
|
||||
// { dg-additional-options -Woverloaded-virtual=2 }
|
||||
|
||||
struct Foo
|
||||
{
|
||||
virtual void g() {}
|
||||
};
|
||||
|
||||
struct Bar : Foo
|
||||
{
|
||||
virtual void g() {}
|
||||
void g(int) {}
|
||||
};
|
Loading…
Add table
Reference in a new issue