зеркало из https://github.com/microsoft/clang-1.git
Make sure that an overriding return type is complete before checking if it's covariant. Fixes PR5920.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92365 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
bba4d023de
Коммит
be2e205add
|
@ -497,6 +497,9 @@ def err_covariant_return_ambiguous_derived_to_base_conv : Error<
|
|||
def err_covariant_return_not_derived : Error<
|
||||
"return type of virtual function %0 is not covariant with the return type of "
|
||||
"the function it overrides (%1 is not derived from %2)">;
|
||||
def err_covariant_return_incomplete : Error<
|
||||
"return type of virtual function %0 is not covariant with the return type of "
|
||||
"the function it overrides (%1 is incomplete)">;
|
||||
def err_covariant_return_type_different_qualifications : Error<
|
||||
"return type of virtual function %0 is not covariant with the return type of "
|
||||
"the function it overrides (%1 has different qualifiers than %2)">;
|
||||
|
|
|
@ -5528,6 +5528,15 @@ 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 (RequireCompleteType(New->getLocation(), NewClassTy,
|
||||
PDiag(diag::err_covariant_return_incomplete)
|
||||
<< New->getDeclName()))
|
||||
return true;
|
||||
|
||||
if (!Context.hasSameUnqualifiedType(NewClassTy, OldClassTy)) {
|
||||
// Check if the new class derives from the old class.
|
||||
if (!IsDerivedFrom(NewClassTy, OldClassTy)) {
|
||||
|
|
|
@ -104,6 +104,35 @@ namespace T7 {
|
|||
};
|
||||
}
|
||||
|
||||
namespace T8 {
|
||||
struct a { };
|
||||
struct b; // expected-note {{forward declaration of 'struct T8::b'}}
|
||||
|
||||
class A {
|
||||
virtual a *f();
|
||||
};
|
||||
|
||||
class B : A {
|
||||
b* f(); // expected-error {{return type of virtual function 'f' is not covariant with the return type of the function it overrides ('struct T8::b' is incomplete)}}
|
||||
};
|
||||
}
|
||||
|
||||
namespace T9 {
|
||||
struct a { };
|
||||
|
||||
template<typename T> struct b : a {
|
||||
int a[sizeof(T) ? -1 : -1]; // expected-error {{array size is negative}}
|
||||
};
|
||||
|
||||
class A {
|
||||
virtual a *f();
|
||||
};
|
||||
|
||||
class B : A {
|
||||
virtual b<int> *f(); // expected-note {{in instantiation of template class 'struct T9::b<int>' requested here}}
|
||||
};
|
||||
}
|
||||
|
||||
// PR5656
|
||||
class X0 {
|
||||
virtual void f0();
|
||||
|
@ -150,3 +179,21 @@ void test3() {
|
|||
Bar3<int> b3i; // okay
|
||||
Bar3<float> b3f; // expected-error{{is an abstract class}}
|
||||
}
|
||||
|
||||
// 5920
|
||||
namespace PR5920 {
|
||||
class Base {};
|
||||
|
||||
template <typename T>
|
||||
class Derived : public Base {};
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
virtual Base* Method();
|
||||
};
|
||||
|
||||
class Bar : public Foo {
|
||||
public:
|
||||
virtual Derived<int>* Method();
|
||||
};
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче