Improve our handling of cv-qualifiers in Objective-C pointer
conversions. Previously, we would end up collapsing qualification
conversions into the Objective-C pointer conversion step, including
(possibly) stripping qualifiers that shouldn't be removed.

This generalizes BuildSimilarlyQualifiedPointerType() to also work on
Objective-C object pointers, then eliminates the (redundant, not
totally correct) BuildSimilarlyQualifiedObjCObjectPointerType()
function.

Fixes <rdar://problem/8714395>.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120607 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaObjCXX/overload.mm b/test/SemaObjCXX/overload.mm
index 7ac4d82..84aedf6 100644
--- a/test/SemaObjCXX/overload.mm
+++ b/test/SemaObjCXX/overload.mm
@@ -31,8 +31,8 @@
 float& f(B*); // expected-note {{candidate}}
 void g(A*);
 
-int& h(A*);
-float& h(id);
+int& h(A*); // expected-note{{candidate}}
+float& h(id); // expected-note{{candidate}}
 
 void test0(A* a, B* b, id val) {
   int& i1 = f(a);
@@ -46,13 +46,14 @@
   g(val);
   int& i2 = h(a);
   float& f3 = h(val);
-  //  int& i3 = h(b); FIXME: we match GCC here, but shouldn't this work?
+
+  // FIXME: we match GCC here, but shouldn't this work?
+  int& i3 = h(b); // expected-error{{call to 'h' is ambiguous}}
 }
 
-// We make these errors instead of warnings.  Is that okay?
 void test1(A* a) {
-  B* b = a; // expected-error{{cannot initialize a variable of type 'B *' with an lvalue of type 'A *'}}
-  B *c; c = a; // expected-error{{assigning to 'B *' from incompatible type 'A *'}}
+  B* b = a; // expected-warning{{incompatible pointer types converting 'A *' to type 'B *'}}
+  B *c; c = a; // expected-warning{{incompatible pointer types assigning to 'A *' from 'B *'}}
 }
 
 void test2(A** ap) {
@@ -64,18 +65,16 @@
 int& cv(A*); // expected-note {{previous declaration}} expected-note 2 {{not viable}}
 float& cv(const A*); // expected-error {{cannot be overloaded}}
 
-int& cv2(void*); // expected-note 2 {{candidate}}
-float& cv2(const void*); // expected-note 2 {{candidate}}
+int& cv2(void*);
+float& cv2(const void*);
 
 void cv_test(A* a, B* b, const A* ac, const B* bc) {
   int &i1 = cv(a);
   int &i2 = cv(b);
   float &f1 = cv(ac); // expected-error {{no matching function}}
   float &f2 = cv(bc); // expected-error {{no matching function}}
-
-  // FIXME: these should not be ambiguous
-  int& i3 = cv2(a); // expected-error {{ambiguous}}
-  float& f3 = cv2(ac); // expected-error {{ambiguous}}
+  int& i3 = cv2(a);
+  float& f3 = cv2(ac);
 }
 
 // We agree with GCC that these can't be overloaded.
@@ -124,3 +123,22 @@
     foo(b); // expected-error {{call to 'foo' is ambiguous}}
   }
 }
+
+namespace rdar8714395 {
+  int &f(const void*);
+  float &f(const Foo*);
+
+  int &f2(const void*);
+  float &f2(Foo const* const *);
+
+  int &f3(const void*);
+  float &f3(Foo const**);
+
+  void g(Foo *p) {
+    float &fr = f(p);
+    float &fr2 = f2(&p);
+    int &ir = f3(&p);
+  }
+
+  
+}