[PATCH] D31597: [ObjC++] Conversions from specialized to non-specialized objective-c object type should be preferred over conversions to other object pointers

2017-04-06 Thread Alex Lorenz via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL299648: [ObjC++] Conversions from specialized to 
non-specialized Objective-C generic (authored by arphaman).

Changed prior to commit:
  https://reviews.llvm.org/D31597?vs=93845=94360#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D31597

Files:
  cfe/trunk/lib/Sema/SemaOverload.cpp
  cfe/trunk/test/SemaObjCXX/overload.mm


Index: cfe/trunk/lib/Sema/SemaOverload.cpp
===
--- cfe/trunk/lib/Sema/SemaOverload.cpp
+++ cfe/trunk/lib/Sema/SemaOverload.cpp
@@ -4047,7 +4047,7 @@
 = S.Context.canAssignObjCInterfaces(ToPtr1, ToPtr2);
   bool ToAssignRight
 = S.Context.canAssignObjCInterfaces(ToPtr2, ToPtr1);
-  
+
   // A conversion to an a non-id object pointer type or qualified 'id' 
   // type is better than a conversion to 'id'.
   if (ToPtr1->isObjCIdType() &&
@@ -4081,11 +4081,25 @@
 return ImplicitConversionSequence::Better;
 
   //   -- "conversion of C* to B* is better than conversion of C* to A*,"
-  if (S.Context.hasSameType(FromType1, FromType2) && 
+  if (S.Context.hasSameType(FromType1, FromType2) &&
   !FromPtr1->isObjCIdType() && !FromPtr1->isObjCClassType() &&
-  (ToAssignLeft != ToAssignRight))
+  (ToAssignLeft != ToAssignRight)) {
+if (FromPtr1->isSpecialized()) {
+  // "conversion of B * to B * is better than conversion of B * to
+  // C *.
+  bool IsFirstSame =
+  FromPtr1->getInterfaceDecl() == ToPtr1->getInterfaceDecl();
+  bool IsSecondSame =
+  FromPtr1->getInterfaceDecl() == ToPtr2->getInterfaceDecl();
+  if (IsFirstSame) {
+if (!IsSecondSame)
+  return ImplicitConversionSequence::Better;
+  } else if (IsSecondSame)
+return ImplicitConversionSequence::Worse;
+}
 return ToAssignLeft? ImplicitConversionSequence::Worse
: ImplicitConversionSequence::Better;
+  }
 
   //   -- "conversion of B* to A* is better than conversion of C* to A*,"
   if (S.Context.hasSameUnqualifiedType(ToType1, ToType2) &&
Index: cfe/trunk/test/SemaObjCXX/overload.mm
===
--- cfe/trunk/test/SemaObjCXX/overload.mm
+++ cfe/trunk/test/SemaObjCXX/overload.mm
@@ -174,3 +174,30 @@
   void f(Class) { }
   void f(id) { }
 }
+
+@interface NSDictionary<__covariant KeyType, __covariant ObjectType> : A
+@end
+
+@interface NSMutableDictionary : NSDictionary
+@end
+
+namespace rdar20124827 {
+
+int overload(NSDictionary *) { return 1; }
+
+__attribute__((deprecated))  // expected-note {{'overload' has been explicitly 
marked deprecated here}}
+int overload(NSMutableDictionary *) { return 0; }
+
+__attribute__((deprecated))
+void overload2(NSDictionary *); // expected-note {{candidate function}}
+void overload2(NSDictionary *); // expected-note {{candidate 
function}}
+
+void test(NSDictionary *d1, NSDictionary *d2, NSMutableDictionary *m1) {
+  overload(d1);
+  overload(d2); // no warning
+  overload(m1); // expected-warning {{'overload' is deprecated}}
+  overload2(d2); // no warning
+  overload2(m1); // expected-error {{call to 'overload2' is ambiguous}}
+}
+
+}


Index: cfe/trunk/lib/Sema/SemaOverload.cpp
===
--- cfe/trunk/lib/Sema/SemaOverload.cpp
+++ cfe/trunk/lib/Sema/SemaOverload.cpp
@@ -4047,7 +4047,7 @@
 = S.Context.canAssignObjCInterfaces(ToPtr1, ToPtr2);
   bool ToAssignRight
 = S.Context.canAssignObjCInterfaces(ToPtr2, ToPtr1);
-  
+
   // A conversion to an a non-id object pointer type or qualified 'id' 
   // type is better than a conversion to 'id'.
   if (ToPtr1->isObjCIdType() &&
@@ -4081,11 +4081,25 @@
 return ImplicitConversionSequence::Better;
 
   //   -- "conversion of C* to B* is better than conversion of C* to A*,"
-  if (S.Context.hasSameType(FromType1, FromType2) && 
+  if (S.Context.hasSameType(FromType1, FromType2) &&
   !FromPtr1->isObjCIdType() && !FromPtr1->isObjCClassType() &&
-  (ToAssignLeft != ToAssignRight))
+  (ToAssignLeft != ToAssignRight)) {
+if (FromPtr1->isSpecialized()) {
+  // "conversion of B * to B * is better than conversion of B * to
+  // C *.
+  bool IsFirstSame =
+  FromPtr1->getInterfaceDecl() == ToPtr1->getInterfaceDecl();
+  bool IsSecondSame =
+  FromPtr1->getInterfaceDecl() == ToPtr2->getInterfaceDecl();
+  if (IsFirstSame) {
+if (!IsSecondSame)
+  return ImplicitConversionSequence::Better;
+  } else if (IsSecondSame)
+return ImplicitConversionSequence::Worse;
+}
 return ToAssignLeft? 

[PATCH] D31597: [ObjC++] Conversions from specialized to non-specialized objective-c object type should be preferred over conversions to other object pointers

2017-04-04 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak accepted this revision.
ahatanak added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rL LLVM

https://reviews.llvm.org/D31597



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31597: [ObjC++] Conversions from specialized to non-specialized objective-c object type should be preferred over conversions to other object pointers

2017-04-03 Thread Alex Lorenz via Phabricator via cfe-commits
arphaman created this revision.

Right now Clang will select incorrect overload when the Objective-C interface 
type is specialized, e.g.:

  void overload(Base *b);
  void overload(Derived *d);
  void test(Base b) {
overload(b); // This will select (Derived *) overload
  }

This patch ensures that the conversion from specialized to non-specialized type 
that points to the same interface is better than the other objective-c pointer 
conversions.


Repository:
  rL LLVM

https://reviews.llvm.org/D31597

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


Index: test/SemaObjCXX/overload.mm
===
--- test/SemaObjCXX/overload.mm
+++ test/SemaObjCXX/overload.mm
@@ -174,3 +174,30 @@
   void f(Class) { }
   void f(id) { }
 }
+
+@interface NSDictionary<__covariant KeyType, __covariant ObjectType> : A
+@end
+
+@interface NSMutableDictionary : NSDictionary
+@end
+
+namespace rdar20124827 {
+
+int overload(NSDictionary *) { return 1; }
+
+__attribute__((deprecated))  // expected-note {{'overload' has been explicitly 
marked deprecated here}}
+int overload(NSMutableDictionary *) { return 0; }
+
+__attribute__((deprecated))
+void overload2(NSDictionary *); // expected-note {{candidate function}}
+void overload2(NSDictionary *); // expected-note {{candidate 
function}}
+
+void test(NSDictionary *d1, NSDictionary *d2, NSMutableDictionary *m1) {
+  overload(d1);
+  overload(d2); // no warning
+  overload(m1); // expected-warning {{'overload' is deprecated}}
+  overload2(d2); // no warning
+  overload2(m1); // expected-error {{call to 'overload2' is ambiguous}}
+}
+
+}
Index: lib/Sema/SemaOverload.cpp
===
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -4048,7 +4048,7 @@
 = S.Context.canAssignObjCInterfaces(ToPtr1, ToPtr2);
   bool ToAssignRight
 = S.Context.canAssignObjCInterfaces(ToPtr2, ToPtr1);
-  
+
   // A conversion to an a non-id object pointer type or qualified 'id' 
   // type is better than a conversion to 'id'.
   if (ToPtr1->isObjCIdType() &&
@@ -4082,11 +4082,25 @@
 return ImplicitConversionSequence::Better;
 
   //   -- "conversion of C* to B* is better than conversion of C* to A*,"
-  if (S.Context.hasSameType(FromType1, FromType2) && 
+  if (S.Context.hasSameType(FromType1, FromType2) &&
   !FromPtr1->isObjCIdType() && !FromPtr1->isObjCClassType() &&
-  (ToAssignLeft != ToAssignRight))
+  (ToAssignLeft != ToAssignRight)) {
+if (FromPtr1->isSpecialized()) {
+  // "conversion of B * to B * is better than conversion of B * to
+  // C *.
+  bool IsFirstSame =
+  FromPtr1->getInterfaceDecl() == ToPtr1->getInterfaceDecl();
+  bool IsSecondSame =
+  FromPtr1->getInterfaceDecl() == ToPtr2->getInterfaceDecl();
+  if (IsFirstSame) {
+if (!IsSecondSame)
+  return ImplicitConversionSequence::Better;
+  } else if (IsSecondSame)
+return ImplicitConversionSequence::Worse;
+}
 return ToAssignLeft? ImplicitConversionSequence::Worse
: ImplicitConversionSequence::Better;
+  }
 
   //   -- "conversion of B* to A* is better than conversion of C* to A*,"
   if (S.Context.hasSameUnqualifiedType(ToType1, ToType2) &&


Index: test/SemaObjCXX/overload.mm
===
--- test/SemaObjCXX/overload.mm
+++ test/SemaObjCXX/overload.mm
@@ -174,3 +174,30 @@
   void f(Class) { }
   void f(id) { }
 }
+
+@interface NSDictionary<__covariant KeyType, __covariant ObjectType> : A
+@end
+
+@interface NSMutableDictionary : NSDictionary
+@end
+
+namespace rdar20124827 {
+
+int overload(NSDictionary *) { return 1; }
+
+__attribute__((deprecated))  // expected-note {{'overload' has been explicitly marked deprecated here}}
+int overload(NSMutableDictionary *) { return 0; }
+
+__attribute__((deprecated))
+void overload2(NSDictionary *); // expected-note {{candidate function}}
+void overload2(NSDictionary *); // expected-note {{candidate function}}
+
+void test(NSDictionary *d1, NSDictionary *d2, NSMutableDictionary *m1) {
+  overload(d1);
+  overload(d2); // no warning
+  overload(m1); // expected-warning {{'overload' is deprecated}}
+  overload2(d2); // no warning
+  overload2(m1); // expected-error {{call to 'overload2' is ambiguous}}
+}
+
+}
Index: lib/Sema/SemaOverload.cpp
===
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -4048,7 +4048,7 @@
 = S.Context.canAssignObjCInterfaces(ToPtr1, ToPtr2);
   bool ToAssignRight
 = S.Context.canAssignObjCInterfaces(ToPtr2, ToPtr1);
-  
+
   // A conversion to an