http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52103
Bug #: 52103 Summary: need a finer control over -Woverloaded-virtual Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: m...@yandex.ru Let me first explain my use case. I have a large existing non-gcc source which I am porting to a platform supported by gcc. Due to the difference in dialects, I have to insert const modifiers for the function parameters. But when I change the signature of a base class by inserting const, it does not affect the derived classes -- instead, it just breaks inheritance. This is where -Woverloaded-virtual comes to play. Unfortunately, it generates too much noise, rendering the feature almost unusable for this case. Indeed, the best place to hide an important message is a hundred of useless messages of the same sort. (So this is a usability issue.) Considering that -Woverloaded-virtual is rather doing what its name suggests, I propose to implement two finer-tuned options. -Woverloaded-modifiers gives a warning when the two signatures differ only in modifiers like const. (Consider also volatile and restrict.) struct Base{ void f(Base& x){} }; struct Derived: public Base{ void f(const Base& x){} }; -Woverloaded-compatible gives a warning when the two signatures differ in parameter classes, but one of the classes is a descendant of the other. struct First{ void g(Base&x){} }; struct Second{ void g(Derived&x){} }; I underline that -Woverloaded-modifiers and -Woverloaded-compatible should not be limited to virtual functions: virtual could be implied if the function is virtual in the base class. (You may disagree with me here, in this case I want to hear your arguments.) (I do not insist on namely these names, maybe you have some better suggestion(s), but I insist on the functionality.) As to -Woverloaded-virtual, I think, it should be left as it is. Now some code example. Note that with -Woverloaded-modifiers -Woverloaded-compatible there should be no warning for struct ThereIsNoProblem because the argument types are unrelated. $cat inher4.cpp #include <stdio.h> struct Base{ void f(const Base& x){printf("Base.f()\n");} }; struct Derived: public Base{ void f(Base& x){printf("Derived.f()\n");} }; struct First{ virtual void g(Base&x){printf("First.g()\n");} }; struct Second:public First{ virtual void g(Derived&x){printf("Second.g()\n");} }; struct ThereIsNoProblem:public First{ virtual void g(int x){printf("ShouldBeValid.g()");} }; int main() { Base x; Derived y; Base*py=&y; y.f(x); py->f(Base()); Second z; First*pz=&z; //z.g(x); // error: no matching function for call to ‘Second::g(Base&)’ z.g(y); pz->g(x); pz->g(y); } $g++ -Woverloaded-virtual inher4.cpp inher4.cpp:6:28: warning: ‘virtual void First::g(Base&)’ was hidden inher4.cpp:7:42: warning: by ‘virtual void Second::g(Derived&)’ inher4.cpp:6:28: warning: ‘virtual void First::g(Base&)’ was hidden inher4.cpp:8:52: warning: by ‘virtual void ThereIsNoProblem::g(int)’ $./a.out Derived.f() Base.f() Second.g() First.g() First.g() $