]> granicus.if.org Git - clang/commitdiff
When comparing Objective-C pointers during overload resolution to
authorDouglas Gregor <dgregor@apple.com>
Wed, 27 Apr 2011 00:01:52 +0000 (00:01 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 27 Apr 2011 00:01:52 +0000 (00:01 +0000)
determine which is a better conversion to "void*", be sure to perform
the comparison using the safe-for-id
ASTContext::canAssignObjCInterfaces() rather than the asserts-with-id
ASTContext::canAssignObjCInterfaces().

Fixes <rdar://problem/9327203>.

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

lib/Sema/SemaOverload.cpp
test/SemaObjCXX/overload.mm

index 7eb89787f99b80276e7a4da1c6abb7800bd9b481..2e85263ce3ca06efc09cc942d6cc86cce7995d93 100644 (file)
@@ -2631,7 +2631,8 @@ CompareStandardConversionSequences(Sema &S,
     if (ImplicitConversionSequence::CompareKind DerivedCK
           = CompareDerivedToBaseConversions(S, SCS1, SCS2))
       return DerivedCK;
-  } else if (SCS1ConvertsToVoid && SCS2ConvertsToVoid) {
+  } else if (SCS1ConvertsToVoid && SCS2ConvertsToVoid &&
+             !S.Context.hasSameType(SCS1.getFromType(), SCS2.getFromType())) {
     // Both conversion sequences are conversions to void
     // pointers. Compare the source types to determine if there's an
     // inheritance relationship in their sources.
@@ -2645,10 +2646,8 @@ CompareStandardConversionSequences(Sema &S,
     if (SCS2.First == ICK_Array_To_Pointer)
       FromType2 = S.Context.getArrayDecayedType(FromType2);
 
-    QualType FromPointee1
-      = FromType1->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
-    QualType FromPointee2
-      = FromType2->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
+    QualType FromPointee1 = FromType1->getPointeeType().getUnqualifiedType();
+    QualType FromPointee2 = FromType2->getPointeeType().getUnqualifiedType();
 
     if (S.IsDerivedFrom(FromPointee2, FromPointee1))
       return ImplicitConversionSequence::Better;
@@ -2657,13 +2656,19 @@ CompareStandardConversionSequences(Sema &S,
 
     // Objective-C++: If one interface is more specific than the
     // other, it is the better one.
-    const ObjCObjectType* FromIface1 = FromPointee1->getAs<ObjCObjectType>();
-    const ObjCObjectType* FromIface2 = FromPointee2->getAs<ObjCObjectType>();
-    if (FromIface1 && FromIface1) {
-      if (S.Context.canAssignObjCInterfaces(FromIface2, FromIface1))
-        return ImplicitConversionSequence::Better;
-      else if (S.Context.canAssignObjCInterfaces(FromIface1, FromIface2))
-        return ImplicitConversionSequence::Worse;
+    const ObjCObjectPointerType* FromObjCPtr1
+      = FromType1->getAs<ObjCObjectPointerType>();
+    const ObjCObjectPointerType* FromObjCPtr2
+      = FromType2->getAs<ObjCObjectPointerType>();
+    if (FromObjCPtr1 && FromObjCPtr2) {
+      bool AssignLeft = S.Context.canAssignObjCInterfaces(FromObjCPtr1, 
+                                                          FromObjCPtr2);
+      bool AssignRight = S.Context.canAssignObjCInterfaces(FromObjCPtr2, 
+                                                           FromObjCPtr1);
+      if (AssignLeft != AssignRight) {
+        return AssignLeft? ImplicitConversionSequence::Better
+                         : ImplicitConversionSequence::Worse;
+      }
     }
   }
 
index 09cd3ec45cd1225fdca88bbc2ec04b7634f0c277..960a7b228ff336989a3ee9e5b3597951a6f4b577 100644 (file)
@@ -159,3 +159,15 @@ namespace PR9735 {
     int &ir2 = f3(bc);
   }
 }
+
+@interface D : B
+@end
+
+namespace rdar9327203 {
+  int &f(void* const&, int);
+  float &f(void* const&, long);
+  
+  void g(id x) { 
+    int &fr = (f)(x, 0); 
+  }
+}