aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2010-02-15 11:53:20 +0000
committerChandler Carruth <chandlerc@gmail.com>2010-02-15 11:53:20 +0000
commit7385779796f48e234b4fbea27ff205d7dfb34ce8 (patch)
treeeb7ac1d29aaa2132bed22f50992f4210c30bf610
parent94ba380b820cde3fb9d97d5f07ac709ebbb6ac1e (diff)
Defer covariance checks for dependent types. Add test cases that also ensure
they are re-checked on instantiation. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96217 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaDeclCXX.cpp3
-rw-r--r--test/SemaCXX/virtual-override.cpp23
2 files changed, 25 insertions, 1 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index a062724ee4..d47758dc39 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -5577,7 +5577,8 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
QualType NewTy = New->getType()->getAs<FunctionType>()->getResultType();
QualType OldTy = Old->getType()->getAs<FunctionType>()->getResultType();
- if (Context.hasSameType(NewTy, OldTy))
+ if (Context.hasSameType(NewTy, OldTy) ||
+ NewTy->isDependentType() || OldTy->isDependentType())
return false;
// Check if the return types are covariant
diff --git a/test/SemaCXX/virtual-override.cpp b/test/SemaCXX/virtual-override.cpp
index 6f1d83fd8a..09cbfadf9b 100644
--- a/test/SemaCXX/virtual-override.cpp
+++ b/test/SemaCXX/virtual-override.cpp
@@ -215,6 +215,29 @@ namespace PR6110 {
Y1<Derived*, Base*> y;
}
+// Defer checking for covariance if either return type is dependent.
+namespace type_dependent_covariance {
+ struct B {};
+ template <int N> struct TD : public B {};
+ template <> struct TD<1> {};
+
+ template <int N> struct TB {};
+ struct D : public TB<0> {};
+
+ template <int N> struct X {
+ virtual B* f1(); // expected-note{{overridden virtual function is here}}
+ virtual TB<N>* f2(); // expected-note{{overridden virtual function is here}}
+ };
+ template <int N, int M> struct X1 : X<N> {
+ virtual TD<M>* f1(); // expected-error{{return type of virtual function 'f1' is not covariant with the return type of the function it overrides ('TD<1> *'}}
+ virtual D* f2(); // expected-error{{return type of virtual function 'f2' is not covariant with the return type of the function it overrides ('struct type_dependent_covariance::D *' is not derived from 'TB<1> *')}}
+ };
+
+ X1<0, 0> good;
+ X1<0, 1> bad_derived; // expected-note{{instantiation}}
+ X1<1, 0> bad_base; // expected-note{{instantiation}}
+}
+
namespace T10 {
struct A { };
struct B : A { };