[cfe-commits] r113724 - in /cfe/trunk: include/clang/Sema/Overload.h lib/Sema/SemaInit.cpp lib/Sema/SemaOverload.cpp test/SemaCXX/conversion-function.cpp

Douglas Gregor dgregor at apple.com
Sun Sep 12 01:07:23 PDT 2010


Author: dgregor
Date: Sun Sep 12 03:07:23 2010
New Revision: 113724

URL: http://llvm.org/viewvc/llvm-project?rev=113724&view=rev
Log:
When performing overload resolution, only compare the final conversion
sequences for two conversion functions when in fact we are in the text
of initialization by a user-defined conversion sequences. Fixes PR8034.

Modified:
    cfe/trunk/include/clang/Sema/Overload.h
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaCXX/conversion-function.cpp

Modified: cfe/trunk/include/clang/Sema/Overload.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Overload.h?rev=113724&r1=113723&r2=113724&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Overload.h (original)
+++ cfe/trunk/include/clang/Sema/Overload.h Sun Sep 12 03:07:23 2010
@@ -630,7 +630,8 @@
 
     /// Find the best viable function on this overload set, if it exists.
     OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc,
-                                         OverloadCandidateSet::iterator& Best);
+                                         OverloadCandidateSet::iterator& Best,
+                                         bool UserDefinedConversion = false);
 
     void NoteCandidates(Sema &S,
                         OverloadCandidateDisplayKind OCD,
@@ -642,7 +643,8 @@
   bool isBetterOverloadCandidate(Sema &S,
                                  const OverloadCandidate& Cand1,
                                  const OverloadCandidate& Cand2,
-                                 SourceLocation Loc);
+                                 SourceLocation Loc,
+                                 bool UserDefinedConversion = false);
 } // end namespace clang
 
 #endif // LLVM_CLANG_SEMA_OVERLOAD_H

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=113724&r1=113723&r2=113724&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Sun Sep 12 03:07:23 2010
@@ -2389,7 +2389,7 @@
   // Perform overload resolution. If it fails, return the failed result.  
   OverloadCandidateSet::iterator Best;
   if (OverloadingResult Result 
-        = CandidateSet.BestViableFunction(S, DeclLoc, Best))
+        = CandidateSet.BestViableFunction(S, DeclLoc, Best, true))
     return Result;
 
   FunctionDecl *Function = Best->Function;
@@ -2981,7 +2981,7 @@
   // Perform overload resolution. If it fails, return the failed result.  
   OverloadCandidateSet::iterator Best;
   if (OverloadingResult Result
-        = CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
+        = CandidateSet.BestViableFunction(S, DeclLoc, Best, true)) {
     Sequence.SetOverloadFailure(
                         InitializationSequence::FK_UserConversionOverloadFailed, 
                                 Result);
@@ -3276,10 +3276,10 @@
 /// a temporary object, or an error expression if a copy could not be
 /// created.
 static ExprResult CopyObject(Sema &S,
-                                         QualType T,
-                                         const InitializedEntity &Entity,
-                                         ExprResult CurInit,
-                                         bool IsExtraneousCopy) {
+                             QualType T,
+                             const InitializedEntity &Entity,
+                             ExprResult CurInit,
+                             bool IsExtraneousCopy) {
   // Determine which class type we're copying to.
   Expr *CurInitExpr = (Expr *)CurInit.get();
   CXXRecordDecl *Class = 0; 
@@ -4033,7 +4033,8 @@
         << Args[0]->getSourceRange();
       OverloadCandidateSet::iterator Best;
       OverloadingResult Ovl
-        = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
+        = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best,
+                                                true);
       if (Ovl == OR_Deleted) {
         S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
           << Best->Function->isDeleted();

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=113724&r1=113723&r2=113724&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sun Sep 12 03:07:23 2010
@@ -2041,7 +2041,7 @@
   }
 
   OverloadCandidateSet::iterator Best;
-  switch (CandidateSet.BestViableFunction(S, From->getLocStart(), Best)) {
+  switch (CandidateSet.BestViableFunction(S, From->getLocStart(), Best, true)) {
   case OR_Success:
     // Record the standard conversion we used and the conversion function.
     if (CXXConstructorDecl *Constructor
@@ -2769,7 +2769,7 @@
   }
 
   OverloadCandidateSet::iterator Best;
-  switch (CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
+  switch (CandidateSet.BestViableFunction(S, DeclLoc, Best, true)) {
   case OR_Success:
     // C++ [over.ics.ref]p1:
     //
@@ -5329,7 +5329,8 @@
 isBetterOverloadCandidate(Sema &S,
                           const OverloadCandidate& Cand1,
                           const OverloadCandidate& Cand2,
-                          SourceLocation Loc) {
+                          SourceLocation Loc,
+                          bool UserDefinedConversion) {
   // Define viable functions to be better candidates than non-viable
   // functions.
   if (!Cand2.Viable)
@@ -5404,7 +5405,7 @@
   //      the type of the entity being initialized) is a better
   //      conversion sequence than the standard conversion sequence
   //      from the return type of F2 to the destination type.
-  if (Cand1.Function && Cand2.Function &&
+  if (UserDefinedConversion && Cand1.Function && Cand2.Function &&
       isa<CXXConversionDecl>(Cand1.Function) &&
       isa<CXXConversionDecl>(Cand2.Function)) {
     switch (CompareStandardConversionSequences(S,
@@ -5441,12 +5442,14 @@
 /// \returns The result of overload resolution.
 OverloadingResult
 OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
-                                         iterator& Best) {
+                                         iterator& Best,
+                                         bool UserDefinedConversion) {
   // Find the best viable function.
   Best = end();
   for (iterator Cand = begin(); Cand != end(); ++Cand) {
     if (Cand->Viable)
-      if (Best == end() || isBetterOverloadCandidate(S, *Cand, *Best, Loc))
+      if (Best == end() || isBetterOverloadCandidate(S, *Cand, *Best, Loc, 
+                                                     UserDefinedConversion))
         Best = Cand;
   }
 
@@ -5459,7 +5462,8 @@
   for (iterator Cand = begin(); Cand != end(); ++Cand) {
     if (Cand->Viable &&
         Cand != Best &&
-        !isBetterOverloadCandidate(S, *Best, *Cand, Loc)) {
+        !isBetterOverloadCandidate(S, *Best, *Cand, Loc, 
+                                   UserDefinedConversion)) {
       Best = end();
       return OR_Ambiguous;
     }

Modified: cfe/trunk/test/SemaCXX/conversion-function.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conversion-function.cpp?rev=113724&r1=113723&r2=113724&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/conversion-function.cpp (original)
+++ cfe/trunk/test/SemaCXX/conversion-function.cpp Sun Sep 12 03:07:23 2010
@@ -343,3 +343,13 @@
 
   Container<int> test;
 }
+
+namespace PR8034 {
+  struct C {
+    operator int();
+
+  private:
+    template <typename T> operator T();
+  };
+  int x = C().operator int();
+}





More information about the cfe-commits mailing list