[cfe-commits] r97922 - in /cfe/trunk: lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaInit.cpp test/SemaCXX/overload-call.cpp

Douglas Gregor dgregor at apple.com
Sun Mar 7 15:17:44 PST 2010


Author: dgregor
Date: Sun Mar  7 17:17:44 2010
New Revision: 97922

URL: http://llvm.org/viewvc/llvm-project?rev=97922&view=rev
Log:
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.


Modified:
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/test/SemaCXX/overload-call.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=97922&r1=97921&r2=97922&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sun Mar  7 17:17:44 2010
@@ -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;

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=97922&r1=97921&r2=97922&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Sun Mar  7 17:17:44 2010
@@ -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()), 

Modified: cfe/trunk/test/SemaCXX/overload-call.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overload-call.cpp?rev=97922&r1=97921&r2=97922&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/overload-call.cpp (original)
+++ cfe/trunk/test/SemaCXX/overload-call.cpp Sun Mar  7 17:17:44 2010
@@ -386,3 +386,23 @@
     float &fr = f0(C());
   }
 }
+
+namespace PR6483 {
+  struct X0 {
+    operator const unsigned int & () const;
+  };
+
+  struct X1 {
+    operator unsigned int & () const;
+  };
+
+  void f0(const bool &);
+  void f1(bool &); // expected-note 2{{not viable}}
+
+  void g(X0 x0, X1 x1) {
+    f0(x0);
+    f1(x0); // expected-error{{no matching function for call}}
+    f0(x1);
+    f1(x1); // expected-error{{no matching function for call}}
+  }  
+}





More information about the cfe-commits mailing list