g++ fails to compile the following test case: class Baz; class Foo { public: virtual const Baz* getBaz() = 0; }; class Bar : public Foo { public: Baz* getBaz(); }; test-covar.cc:8: error: invalid covariant return type for ‘virtual Baz* Bar::getBaz()’ test-covar.cc:4: error: overriding ‘virtual const Baz* Foo::getBaz()’ However, it compiles successfully if Baz is complete: class Baz { }; class Foo { public: virtual const Baz* getBaz() = 0; }; class Bar : public Foo { public: Baz* getBaz(); }; Reproducible on x86_64-redhat-linux (4.1.2 and 4.4.0) and i386-pc-solaris2.11 (4.2.4, 4.3.4 and 4.5.1). Works correctly with g++ 3.4.3
Confirmed, I don't see why this is a covariant return at all, the difference in qualifier should not change anything.
It certainly is a covariant return type, it meets the criteria in all three bullet points of 10.3 [class.virtual] p5
However p6 says If the return type of D::f differs from the return type of B::f, the class type in the return type of D::f shall be complete at the point of declaration of D::f or shall be the class type D. In this case the class type in the return of Bar::getBaz is neither complete, nor Bar.
Jason, is there a reason to disallow covariant returns where the return type only differs in cv-qualification of the class type? Could the requirement for a complete type be incorporated into the second bullet of p5, since it has to be complete for us to know it's an accessible base? Why does the third bullet of p5 talk about the cv-qualification of pointers and references, when top-level cv-quals in return types are ignored, and references have no cv-quals? Is this an artefact of ARM-era C++? Am I misreading the wording, or should I ask Mike to open an issue?
(In reply to comment #4) > Jason, is there a reason to disallow covariant returns where the return type > only differs in cv-qualification of the class type? > > Could the requirement for a complete type be incorporated into the second > bullet of p5, since it has to be complete for us to know it's an accessible > base? Seems reasonable to me. Or change "if the return type..." to "if the class in the return type...". I note that EDG accepts the testcase. > Why does the third bullet of p5 talk about the cv-qualification of pointers and > references, when top-level cv-quals in return types are ignored, and references > have no cv-quals? Is this an artefact of ARM-era C++? Top-level cv-quals are not ignored in return types, only in parameter types. > Am I misreading the wording, or should I ask Mike to open an issue? I think an issue to clarify this would be appropriate. I'll go ahead and fix the compiler.
Author: jason Date: Fri Mar 4 15:17:55 2011 New Revision: 170676 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=170676 Log: PR c++/46220 * search.c (check_final_overrider): Allow pointer to same incomplete class type with different cv-quals. Added: trunk/gcc/testsuite/g++.dg/inherit/covariant19.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/search.c trunk/gcc/testsuite/ChangeLog
Fixed for 4.6. I'm somewhat reluctant to apply the patch to earlier releases, since G++ was following the letter of the standard already, but am willing to reconsider if someone really wants it in an earlier release.