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:
parent
75fa80bb56
commit
113844d68e
5 changed files with 72 additions and 6 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
14
gcc/testsuite/g++.dg/warn/Woverloaded-virt1.C
Normal file
14
gcc/testsuite/g++.dg/warn/Woverloaded-virt1.C
Normal 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" }
|
||||
};
|
15
gcc/testsuite/g++.dg/warn/Woverloaded-virt2.C
Normal file
15
gcc/testsuite/g++.dg/warn/Woverloaded-virt2.C
Normal 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);
|
||||
};
|
Loading…
Add table
Reference in a new issue