]> granicus.if.org Git - clang/commitdiff
Allow us to compare derived-to-base conversions between a reference
authorDouglas Gregor <dgregor@apple.com>
Thu, 25 Feb 2010 19:01:05 +0000 (19:01 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 25 Feb 2010 19:01:05 +0000 (19:01 +0000)
binding and a copy-construction. Fixes an overloading problem in the
Clang-on-Clang build.

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

lib/Sema/SemaOverload.cpp
test/SemaCXX/overload-call.cpp

index cfb4b91996255bacc0a44fec51565522fe76ee66..784663108b657e52c79c05036051bb70a0ba0ff2 100644 (file)
@@ -2094,32 +2094,6 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
     }
   }
 
-  // Compare based on reference bindings.
-  if (SCS1.ReferenceBinding && SCS2.ReferenceBinding &&
-      SCS1.Second == ICK_Derived_To_Base) {
-    //   -- binding of an expression of type C to a reference of type
-    //      B& is better than binding an expression of type C to a
-    //      reference of type A&,
-    if (Context.hasSameUnqualifiedType(FromType1, FromType2) &&
-        !Context.hasSameUnqualifiedType(ToType1, ToType2)) {
-      if (IsDerivedFrom(ToType1, ToType2))
-        return ImplicitConversionSequence::Better;
-      else if (IsDerivedFrom(ToType2, ToType1))
-        return ImplicitConversionSequence::Worse;
-    }
-
-    //   -- binding of an expression of type B to a reference of type
-    //      A& is better than binding an expression of type C to a
-    //      reference of type A&,
-    if (!Context.hasSameUnqualifiedType(FromType1, FromType2) &&
-        Context.hasSameUnqualifiedType(ToType1, ToType2)) {
-      if (IsDerivedFrom(FromType2, FromType1))
-        return ImplicitConversionSequence::Better;
-      else if (IsDerivedFrom(FromType1, FromType2))
-        return ImplicitConversionSequence::Worse;
-    }
-  }
-  
   // Ranking of member-pointer types.
   if (SCS1.Second == ICK_Pointer_Member && SCS2.Second == ICK_Pointer_Member &&
       FromType1->isMemberPointerType() && FromType2->isMemberPointerType() &&
@@ -2156,9 +2130,13 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
     }
   }
   
-  if (SCS1.CopyConstructor && SCS2.CopyConstructor &&
+  if ((SCS1.ReferenceBinding || SCS1.CopyConstructor) && 
+      (SCS2.ReferenceBinding || SCS2.CopyConstructor) &&
       SCS1.Second == ICK_Derived_To_Base) {
     //   -- conversion of C to B is better than conversion of C to A,
+    //   -- binding of an expression of type C to a reference of type
+    //      B& is better than binding an expression of type C to a
+    //      reference of type A&,
     if (Context.hasSameUnqualifiedType(FromType1, FromType2) &&
         !Context.hasSameUnqualifiedType(ToType1, ToType2)) {
       if (IsDerivedFrom(ToType1, ToType2))
@@ -2168,6 +2146,9 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
     }
 
     //   -- conversion of B to A is better than conversion of C to A.
+    //   -- binding of an expression of type B to a reference of type
+    //      A& is better than binding an expression of type C to a
+    //      reference of type A&,
     if (!Context.hasSameUnqualifiedType(FromType1, FromType2) &&
         Context.hasSameUnqualifiedType(ToType1, ToType2)) {
       if (IsDerivedFrom(FromType2, FromType1))
index 38a26d38ca3ae6c9c95edf3af44a48ffcf5895de..364011c91728bada2d9054709ed69e5684307b7a 100644 (file)
@@ -373,3 +373,16 @@ namespace test4 {
     }
   };
 }
+
+namespace DerivedToBase {
+  struct A { };
+  struct B : A { };
+  struct C : B { };
+  
+  int &f0(const A&);
+  float &f0(B);
+  
+  void g() {
+    float &fr = f0(C());
+  }
+}