Bug 46220 - [4.3/4.4/4.5/4.6 Regression] Error: invalid covariant return type generated for incomplete class type and different qualifer
Summary: [4.3/4.4/4.5/4.6 Regression] Error: invalid covariant return type generated f...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.1.2
: P2 normal
Target Milestone: 4.6.0
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2010-10-28 23:10 UTC by Nathan Keynes
Modified: 2011-03-05 20:35 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2010-10-28 23:16:36


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nathan Keynes 2010-10-28 23:10:40 UTC
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
Comment 1 Andrew Pinski 2010-10-28 23:16:36 UTC
Confirmed, I don't see why this is a covariant return at all, the difference in qualifier should not change anything.
Comment 2 Jonathan Wakely 2010-10-29 00:45:26 UTC
It certainly is a covariant return type, it meets the criteria in all three bullet points of 10.3 [class.virtual] p5
Comment 3 Jonathan Wakely 2010-10-29 00:50:53 UTC
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.
Comment 4 Jonathan Wakely 2010-10-29 01:16:02 UTC
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?
Comment 5 Jason Merrill 2011-03-03 20:52:00 UTC
(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.
Comment 6 Jason Merrill 2011-03-04 15:18:03 UTC
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
Comment 7 Jason Merrill 2011-03-05 20:35:35 UTC
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.