[Sema] Incomplete types are OK for covariant returns

Per C++14 [class.virtual]p8, it is OK for the return type's class type
to be incomplete so long as the return type is the same between the base
and complete classes.

This fixes PR26297.

llvm-svn: 258768
This commit is contained in:
David Majnemer 2016-01-26 01:37:01 +00:00
parent 5ec41f3b74
commit d3d91bd17f
2 changed files with 25 additions and 12 deletions

View File

@ -13020,19 +13020,20 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
return true;
}
// C++ [class.virtual]p6:
// 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.
if (const RecordType *RT = NewClassTy->getAs<RecordType>()) {
if (!RT->isBeingDefined() &&
RequireCompleteType(New->getLocation(), NewClassTy,
diag::err_covariant_return_incomplete,
New->getDeclName()))
return true;
}
if (!Context.hasSameUnqualifiedType(NewClassTy, OldClassTy)) {
// C++14 [class.virtual]p8:
// If the class type in the covariant return type of D::f differs from
// that 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.
if (const RecordType *RT = NewClassTy->getAs<RecordType>()) {
if (!RT->isBeingDefined() &&
RequireCompleteType(New->getLocation(), NewClassTy,
diag::err_covariant_return_incomplete,
New->getDeclName()))
return true;
}
// Check if the new class derives from the old class.
if (!IsDerivedFrom(New->getLocation(), NewClassTy, OldClassTy)) {
Diag(New->getLocation(), diag::err_covariant_return_not_derived)

View File

@ -289,3 +289,15 @@ namespace PR8168 {
static void foo() {} // expected-error{{'static' member function 'foo' overrides a virtual function}}
};
}
namespace PR26297 {
struct Incomplete;
struct Base {
virtual const Incomplete *meow() = 0;
};
struct Derived : Base {
virtual Incomplete *meow() override { return nullptr; }
};
}