]> granicus.if.org Git - clang/commitdiff
Defer covariance checks for dependent types. Add test cases that also ensure
authorChandler Carruth <chandlerc@gmail.com>
Mon, 15 Feb 2010 11:53:20 +0000 (11:53 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Mon, 15 Feb 2010 11:53:20 +0000 (11:53 +0000)
they are re-checked on instantiation.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96217 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/virtual-override.cpp

index a062724ee4125f461b9ff14955cb0ca07b7f697b..d47758dc39c1efced5af1757e870852e7fab9b8e 100644 (file)
@@ -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
index 6f1d83fd8ae8382ddef485be973fff772b26ddeb..09cbfadf9b37dabd861300191c64ed831a0bf844 100644 (file)
@@ -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 { };