[cfe-commits] r94183 - in /cfe/trunk: lib/Sema/SemaDeclCXX.cpp test/SemaCXX/virtual-override.cpp

Anders Carlsson andersca at mac.com
Fri Jan 22 09:37:20 PST 2010


Author: andersca
Date: Fri Jan 22 11:37:20 2010
New Revision: 94183

URL: http://llvm.org/viewvc/llvm-project?rev=94183&view=rev
Log:
No need to canonicalize the type and use dyn_cast. Also, correctly diagnose trying to override a function returning an lvalue reference with a function overriding an rvalue reference.

Modified:
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/SemaCXX/virtual-override.cpp

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Jan 22 11:37:20 2010
@@ -5611,26 +5611,24 @@
   QualType NewTy = New->getType()->getAs<FunctionType>()->getResultType();
   QualType OldTy = Old->getType()->getAs<FunctionType>()->getResultType();
 
-  QualType CNewTy = Context.getCanonicalType(NewTy);
-  QualType COldTy = Context.getCanonicalType(OldTy);
-
-  if (CNewTy == COldTy &&
-      CNewTy.getLocalCVRQualifiers() == COldTy.getLocalCVRQualifiers())
+  if (Context.hasSameType(NewTy, OldTy))
     return false;
 
   // Check if the return types are covariant
   QualType NewClassTy, OldClassTy;
 
   /// Both types must be pointers or references to classes.
-  if (PointerType *NewPT = dyn_cast<PointerType>(CNewTy)) {
-    if (PointerType *OldPT = dyn_cast<PointerType>(COldTy)) {
+  if (const PointerType *NewPT = NewTy->getAs<PointerType>()) {
+    if (const PointerType *OldPT = OldTy->getAs<PointerType>()) {
       NewClassTy = NewPT->getPointeeType();
       OldClassTy = OldPT->getPointeeType();
     }
-  } else if (ReferenceType *NewRT = dyn_cast<ReferenceType>(CNewTy)) {
-    if (ReferenceType *OldRT = dyn_cast<ReferenceType>(COldTy)) {
-      NewClassTy = NewRT->getPointeeType();
-      OldClassTy = OldRT->getPointeeType();
+  } else if (const ReferenceType *NewRT = NewTy->getAs<ReferenceType>()) {
+    if (const ReferenceType *OldRT = OldTy->getAs<ReferenceType>()) {
+      if (NewRT->getTypeClass() == OldRT->getTypeClass()) {
+        NewClassTy = NewRT->getPointeeType();
+        OldClassTy = OldRT->getPointeeType();
+      }
     }
   }
 
@@ -5678,7 +5676,7 @@
   }
 
   // The qualifiers of the return types must be the same.
-  if (CNewTy.getLocalCVRQualifiers() != COldTy.getLocalCVRQualifiers()) {
+  if (NewTy.getLocalCVRQualifiers() != OldTy.getLocalCVRQualifiers()) {
     Diag(New->getLocation(),
          diag::err_covariant_return_type_different_qualifications)
     << New->getDeclName() << NewTy << OldTy;

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

==============================================================================
--- cfe/trunk/test/SemaCXX/virtual-override.cpp (original)
+++ cfe/trunk/test/SemaCXX/virtual-override.cpp Fri Jan 22 11:37:20 2010
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -faccess-control -verify %s
+// RUN: %clang_cc1 -fsyntax-only -faccess-control -verify %s -std=c++0x
 namespace T1 {
 
 class A {
@@ -214,3 +214,42 @@
   template <typename T1, typename T> class Y1 : public Y<T> { virtual T1 f(); };
   Y1<Derived*, Base*> y;
 }
+
+namespace T10 {
+  struct A { };
+  struct B : A { };
+
+  struct C { 
+    virtual A&& f();
+  };
+
+  struct D : C {
+    virtual B&& f();
+  };
+};
+
+namespace T11 {
+  struct A { };
+  struct B : A { };
+
+  struct C { 
+    virtual A& f(); // expected-note {{overridden virtual function is here}}
+  };
+
+  struct D : C {
+    virtual B&& f(); // expected-error {{virtual function 'f' has a different return type ('struct T11::B &&') than the function it overrides (which has return type 'struct T11::A &')}}
+  };
+};
+
+namespace T12 {
+  struct A { };
+  struct B : A { };
+
+  struct C { 
+    virtual A&& f(); // expected-note {{overridden virtual function is here}}
+  };
+
+  struct D : C {
+    virtual B& f(); // expected-error {{virtual function 'f' has a different return type ('struct T12::B &') than the function it overrides (which has return type 'struct T12::A &&')}}
+  };
+};





More information about the cfe-commits mailing list