When performing template argument deduction, match Objective C pointers
against pointer patterns.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103706 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index b85f2bd..733d0e9 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -482,14 +482,20 @@
 
     //     T *
     case Type::Pointer: {
-      const PointerType *PointerArg = Arg->getAs<PointerType>();
-      if (!PointerArg)
+      QualType PointeeType;
+      if (const PointerType *PointerArg = Arg->getAs<PointerType>()) {
+        PointeeType = PointerArg->getPointeeType();
+      } else if (const ObjCObjectPointerType *PointerArg
+                   = Arg->getAs<ObjCObjectPointerType>()) {
+        PointeeType = PointerArg->getPointeeType();
+      } else {
         return Sema::TDK_NonDeducedMismatch;
+      }
 
       unsigned SubTDF = TDF & (TDF_IgnoreQualifiers | TDF_DerivedClass);
       return DeduceTemplateArguments(S, TemplateParams,
                                    cast<PointerType>(Param)->getPointeeType(),
-                                     PointerArg->getPointeeType(),
+                                     PointeeType,
                                      Info, Deduced, SubTDF);
     }
 
diff --git a/test/SemaObjCXX/deduction.mm b/test/SemaObjCXX/deduction.mm
new file mode 100644
index 0000000..2c153aa
--- /dev/null
+++ b/test/SemaObjCXX/deduction.mm
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@class NSString;
+
+// Reduced from WebKit.
+namespace test0 {
+  template <typename T> struct RemovePointer {
+    typedef T Type;
+  };
+
+  template <typename T> struct RemovePointer<T*> {
+    typedef T Type;
+  };
+
+  template <typename T> struct RetainPtr {
+    typedef typename RemovePointer<T>::Type ValueType;
+    typedef ValueType* PtrType;
+    RetainPtr(PtrType ptr);
+  };
+ 
+  void test(NSString *S) {
+    RetainPtr<NSString*> ptr(S);
+  }
+}