[cfe-commits] r92365 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDeclCXX.cpp test/SemaCXX/virtual-override.cpp

Anders Carlsson andersca at mac.com
Thu Dec 31 10:34:25 PST 2009


Author: andersca
Date: Thu Dec 31 12:34:24 2009
New Revision: 92365

URL: http://llvm.org/viewvc/llvm-project?rev=92365&view=rev
Log:
Make sure that an overriding return type is complete before checking if it's covariant. Fixes PR5920.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/SemaCXX/virtual-override.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=92365&r1=92364&r2=92365&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Dec 31 12:34:24 2009
@@ -497,6 +497,9 @@
 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)">;

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=92365&r1=92364&r2=92365&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Dec 31 12:34:24 2009
@@ -5528,6 +5528,15 @@
     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)) {

Modified: cfe/trunk/test/SemaCXX/virtual-override.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/virtual-override.cpp?rev=92365&r1=92364&r2=92365&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/virtual-override.cpp (original)
+++ cfe/trunk/test/SemaCXX/virtual-override.cpp Thu Dec 31 12:34:24 2009
@@ -104,6 +104,35 @@
   };
 }
 
+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 @@
   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();
+  };
+}





More information about the cfe-commits mailing list