c++: Include -Woverloaded-virtual in -Wall [PR87729]

This seems like a good warning to have in -Wall, as requested.  But as
pointed out in PR20423, some users want a warning only when a derived
function doesn't override any base function.  So let's put that lesser
version in -Wall (and -Woverloaded-virtual=1) while leaving the semantics
for the existing option the same.

	PR c++/87729
	PR c++/20423

gcc/c-family/ChangeLog:

	* c.opt (Woverloaded-virtual): Add levels, include in -Wall.

gcc/ChangeLog:

	* doc/invoke.texi: Document changes.

gcc/cp/ChangeLog:

	* class.cc (warn_hidden): Handle -Woverloaded-virtual=1.

gcc/testsuite/ChangeLog:

	* g++.dg/warn/Woverloaded-virt1.C: New test.
	* g++.dg/warn/Woverloaded-virt2.C: New test.
This commit is contained in:
Jason Merrill 2022-06-24 14:40:12 -04:00
parent 75fa80bb56
commit 113844d68e
5 changed files with 72 additions and 6 deletions

View file

@ -1126,7 +1126,11 @@ C ObjC C++ ObjC++ Var(warn_overlength_strings) Warning LangEnabledBy(C ObjC C++
Warn if a string is longer than the maximum portable length specified by the standard.
Woverloaded-virtual
C++ ObjC++ Var(warn_overloaded_virtual) Warning
C++ ObjC++ Warning Alias(Woverloaded-virtual=,2,0)
Warn about overloaded virtual function names.
Woverloaded-virtual=
C++ ObjC++ Joined UInteger IntegerRange(0,2) Var(warn_overloaded_virtual) Warning LangEnabledBy(C++ ObjC++,Wall,1,0)
Warn about overloaded virtual function names.
Woverride-init

View file

@ -3034,6 +3034,7 @@ warn_hidden (tree t)
continue;
/* Remove any overridden functions. */
bool seen_non_override = false;
for (tree fndecl : ovl_range (fns))
{
if (TREE_CODE (fndecl) == FUNCTION_DECL
@ -3045,20 +3046,28 @@ warn_hidden (tree t)
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;
{
base_fndecls[k] = NULL_TREE;
goto next;
}
}
seen_non_override = true;
next:;
}
if (!seen_non_override && warn_overloaded_virtual == 1)
/* All the derived fns override base virtuals. */
return;
/* 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)
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,
OPT_Woverloaded_virtual_,
"%qD was hidden", base_fndecl))
inform (location_of (fns), " by %qD", fns);
}

View file

@ -4039,6 +4039,7 @@ a C++ program. The new-style casts (@code{dynamic_cast},
less vulnerable to unintended effects and much easier to search for.
@item -Woverloaded-virtual @r{(C++ and Objective-C++ only)}
@itemx -Woverloaded-virtual=@var{n}
@opindex Woverloaded-virtual
@opindex Wno-overloaded-virtual
@cindex overloaded virtual function, warning
@ -4052,7 +4053,7 @@ struct A @{
@};
struct B: public A @{
void f(int);
void f(int); // does not override
@};
@end smallexample
@ -4067,6 +4068,29 @@ b->f();
@noindent
fails to compile.
The optional level suffix controls the behavior when all the
declarations in the derived class override virtual functions in the
base class, even if not all of the base functions are overridden:
@smallexample
struct C @{
virtual void f();
virtual void f(int);
@};
struct D: public C @{
void f(int); // does override
@}
@end smallexample
This pattern is less likely to be a mistake; if D is only used
virtually, the user might have decided that the base class semantics
for some of the overloads are fine.
At level 1, this case does not warn; at level 2, it does.
@option{-Woverloaded-virtual} by itself selects level 2. Level 1 is
included in @option{-Wall}.
@item -Wno-pmf-conversions @r{(C++ and Objective-C++ only)}
@opindex Wno-pmf-conversions
@opindex Wpmf-conversions

View file

@ -0,0 +1,14 @@
// PR c++/87729
// { dg-additional-options -Wall }
class Foo
{
public:
virtual void f(int); // { dg-warning "hidden" }
};
class Bar : public Foo
{
public:
virtual void f(short); // { dg-message "by" }
};

View file

@ -0,0 +1,15 @@
// PR c++/20423
// { dg-additional-options -Wall }
class Foo
{
public:
virtual void f(int);
virtual void f(short);
};
class Bar : public Foo
{
public:
virtual void f(short);
};