Reference binding via user-defined conversion can compute a binding
that is not reference-related (because it requires another implicit
conversion to which we can find). Fixes PR6483.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97922 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 0708d41..b959202 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -4526,20 +4526,23 @@
     OverloadCandidateSet::iterator Best;
     switch (BestViableFunction(CandidateSet, DeclLoc, Best)) {
     case OR_Success:
+      // C++ [over.ics.ref]p1:
+      //
+      //   [...] If the parameter binds directly to the result of
+      //   applying a conversion function to the argument
+      //   expression, the implicit conversion sequence is a
+      //   user-defined conversion sequence (13.3.3.1.2), with the
+      //   second standard conversion sequence either an identity
+      //   conversion or, if the conversion function returns an
+      //   entity of a type that is a derived class of the parameter
+      //   type, a derived-to-base Conversion.
+      if (!Best->FinalConversion.DirectBinding)
+        break;
+
       // This is a direct binding.
       BindsDirectly = true;
 
       if (ICS) {
-        // C++ [over.ics.ref]p1:
-        //
-        //   [...] If the parameter binds directly to the result of
-        //   applying a conversion function to the argument
-        //   expression, the implicit conversion sequence is a
-        //   user-defined conversion sequence (13.3.3.1.2), with the
-        //   second standard conversion sequence either an identity
-        //   conversion or, if the conversion function returns an
-        //   entity of a type that is a derived class of the parameter
-        //   type, a derived-to-base Conversion.
         ICS->setUserDefined();
         ICS->UserDefined.Before = Best->Conversions[0].Standard;
         ICS->UserDefined.After = Best->FinalConversion;
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 98db608..3540cd0 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -2273,10 +2273,17 @@
   Sema::ReferenceCompareResult NewRefRelationship
     = S.CompareReferenceRelationship(DeclLoc, T1, T2.getNonReferenceType(),
                                      NewDerivedToBase);
-  assert(NewRefRelationship != Sema::Ref_Incompatible &&
-         "Overload resolution picked a bad conversion function");
-  (void)NewRefRelationship;
-  if (NewDerivedToBase)
+  if (NewRefRelationship == Sema::Ref_Incompatible) {
+    // If the type we've converted to is not reference-related to the
+    // type we're looking for, then there is another conversion step
+    // we need to perform to produce a temporary of the right type
+    // that we'll be binding to.
+    ImplicitConversionSequence ICS;
+    ICS.setStandard();
+    ICS.Standard = Best->FinalConversion;
+    T2 = ICS.Standard.getToType(2);
+    Sequence.AddConversionSequenceStep(ICS, T2);
+  } else if (NewDerivedToBase)
     Sequence.AddDerivedToBaseCastStep(
                                 S.Context.getQualifiedType(T1,
                                   T2.getNonReferenceType().getQualifiers()),