summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp25
-rw-r--r--clang/test/SemaCXX/virtual-override.cpp12
2 files changed, 25 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 82d81a85fa9..fc1c2ec75f4 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -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)
diff --git a/clang/test/SemaCXX/virtual-override.cpp b/clang/test/SemaCXX/virtual-override.cpp
index ec884f36323..42491178482 100644
--- a/clang/test/SemaCXX/virtual-override.cpp
+++ b/clang/test/SemaCXX/virtual-override.cpp
@@ -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; }
+};
+}
OpenPOWER on IntegriCloud