Introduce a specific representation for the ambiguous implicit conversion
sequence.  Lots of small relevant changes.  Fixes some serious problems with
ambiguous conversions;  also possibly improves associated diagnostics.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93214 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaCXX/ambig-user-defined-conversions.cpp b/test/SemaCXX/ambig-user-defined-conversions.cpp
index 8ac822f..5e0a2e3 100644
--- a/test/SemaCXX/ambig-user-defined-conversions.cpp
+++ b/test/SemaCXX/ambig-user-defined-conversions.cpp
@@ -21,6 +21,13 @@
     func(b1, f()); // expected-error {{call to 'func' is ambiguous}}
     return f(); // expected-error {{conversion from 'struct test0::B' to 'int const' is ambiguous}}
   }
+
+  // This used to crash when comparing the two operands.
+  void func2(const char cc); // expected-note {{candidate function}}
+  void func2(const int ci); // expected-note {{candidate function}}
+  void Test2() {
+    func2(b1); // expected-error {{call to 'func2' is ambiguous}}
+  }
 }
 
 namespace test1 {
diff --git a/test/SemaCXX/builtin-ptrtomember-overload-1.cpp b/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
index 137503b..b1b0b98 100644
--- a/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
+++ b/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
@@ -40,7 +40,7 @@
 }
 
 void foo1(C1 c1, int E::* pmf) {
-        // FIXME. Error reporting needs much improvement here.
-        int i = c1->*pmf;	// expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'struct C1'}} \
-                                // expected-note {{because of ambiguity in conversion of 'struct C1' to 'struct E *'}}
+        int i = c1->*pmf;	// expected-error {{use of overloaded operator '->*' is ambiguous}} \
+                                // expected-note {{because of ambiguity in conversion of 'struct C1' to 'struct E *'}} \
+                                // expected-note 4 {{built-in candidate operator}}
 }
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
index 0617cd5..8eaff78 100644
--- a/test/SemaCXX/conditional-expr.cpp
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -7,8 +7,8 @@
 struct ToBool { explicit operator bool(); };
 
 struct B;
-struct A { A(); A(const B&); };
-struct B { operator A() const; };
+struct A { A(); A(const B&); }; // expected-note 2 {{candidate constructor}}
+struct B { operator A() const; }; // expected-note 2 {{candidate function}}
 struct I { operator int(); };
 struct J { operator I(); };
 struct K { operator double(); };
@@ -50,8 +50,8 @@
 enum Enum { EVal };
 
 struct Ambig {
-  operator short();
-  operator signed char();
+  operator short(); // expected-note 2 {{candidate function}}
+  operator signed char(); // expected-note 2 {{candidate function}}
 };
 
 void test()
@@ -129,10 +129,10 @@
   vfn pfn = i1 ? F() : test;
   pfn = i1 ? test : F();
   // these are ambiguous - better messages would be nice
-  (void)(i1 ? A() : B()); // expected-error {{incompatible operand types}}
-  (void)(i1 ? B() : A()); // expected-error {{incompatible operand types}}
-  (void)(i1 ? 1 : Ambig()); // expected-error {{incompatible operand types}}
-  (void)(i1 ? Ambig() : 1); // expected-error {{incompatible operand types}}
+  (void)(i1 ? A() : B()); // expected-error {{conversion from 'struct B' to 'struct A' is ambiguous}}
+  (void)(i1 ? B() : A()); // expected-error {{conversion from 'struct B' to 'struct A' is ambiguous}}
+  (void)(i1 ? 1 : Ambig()); // expected-error {{conversion from 'struct Ambig' to 'int' is ambiguous}}
+  (void)(i1 ? Ambig() : 1); // expected-error {{conversion from 'struct Ambig' to 'int' is ambiguous}}
   // By the way, this isn't an lvalue:
   &(i1 ? i1 : i2); // expected-error {{address expression must be an lvalue or a function designator}}