[cfe-commits] r82596 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaOverload.cpp lib/Sema/SemaOverload.h test/SemaCXX/ambig-user-defined-convesions.cpp

Fariborz Jahanian fjahanian at apple.com
Tue Sep 22 17:58:07 PDT 2009


Author: fjahanian
Date: Tue Sep 22 19:58:07 2009
New Revision: 82596

URL: http://llvm.org/viewvc/llvm-project?rev=82596&view=rev
Log:
Produce detailed diagnostics when overload
resolution failed to select a candidate due to
ambiguity in type conversion function selection.


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/lib/Sema/SemaOverload.h
    cfe/trunk/test/SemaCXX/ambig-user-defined-convesions.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=82596&r1=82595&r2=82596&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Sep 22 19:58:07 2009
@@ -763,6 +763,8 @@
 def err_ovl_deleted_member_call : Error<
   "call to %select{unavailable|deleted}0 member function %1">;
 def err_ovl_candidate : Note<"candidate function">;
+def err_ovl_candidate_not_viable : Note<"function not viable because"
+                                        " of ambiguity in conversion of argument %0">;
 def err_ovl_template_candidate : Note<
   "candidate function template specialization %0">;
 def err_ovl_candidate_deleted : Note<

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=82596&r1=82595&r2=82596&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Sep 22 19:58:07 2009
@@ -411,13 +411,15 @@
                             bool InOverloadResolution) {
   ImplicitConversionSequence ICS;
   OverloadCandidateSet Conversions;
+  OverloadingResult UserDefResult = OR_Success;
   if (IsStandardConversion(From, ToType, InOverloadResolution, ICS.Standard))
     ICS.ConversionKind = ImplicitConversionSequence::StandardConversion;
   else if (getLangOptions().CPlusPlus &&
-           IsUserDefinedConversion(From, ToType, ICS.UserDefined,
+           (UserDefResult = IsUserDefinedConversion(From, ToType, 
+                                   ICS.UserDefined,
                                    Conversions,
                                    !SuppressUserConversions, AllowExplicit,
-                                   ForceRValue) == OR_Success) {
+                                   ForceRValue)) == OR_Success) {
     ICS.ConversionKind = ImplicitConversionSequence::UserDefinedConversion;
     // C++ [over.ics.user]p4:
     //   A conversion of an expression of class type to the same class
@@ -454,8 +456,14 @@
     if (SuppressUserConversions &&
         ICS.ConversionKind == ImplicitConversionSequence::UserDefinedConversion)
       ICS.ConversionKind = ImplicitConversionSequence::BadConversion;
-  } else
+  } else {
     ICS.ConversionKind = ImplicitConversionSequence::BadConversion;
+    if (UserDefResult == OR_Ambiguous) {
+      for (OverloadCandidateSet::iterator Cand = Conversions.begin();
+           Cand != Conversions.end(); ++Cand)
+        ICS.ConversionFunctionSet.push_back(Cand->Function);
+    }
+  }
 
   return ICS;
 }
@@ -3868,8 +3876,27 @@
                               *Cand->Function->getTemplateSpecializationArgs());
         } else {
           // Normal function
-          // FIXME: Give a better reason!
-          Diag(Cand->Function->getLocation(), diag::err_ovl_candidate);
+          bool errReported = false;
+          if (!Cand->Viable && Cand->Conversions.size() > 0) {
+            for (int i = Cand->Conversions.size()-1; i >= 0; i--) {
+              const ImplicitConversionSequence &Conversion = 
+                                                        Cand->Conversions[i];
+              if ((Conversion.ConversionKind != 
+                   ImplicitConversionSequence::BadConversion) ||
+                  Conversion.ConversionFunctionSet.size() == 0)
+                continue;
+              Diag(Cand->Function->getLocation(), 
+                   diag::err_ovl_candidate_not_viable) << (i+1);
+              errReported = true;
+              for (int j = Conversion.ConversionFunctionSet.size()-1; 
+                   j >= 0; j--) {
+                FunctionDecl *Func = Conversion.ConversionFunctionSet[j];
+                Diag(Func->getLocation(), diag::err_ovl_candidate);
+              }
+            }
+          }
+          if (!errReported)
+            Diag(Cand->Function->getLocation(), diag::err_ovl_candidate);
         }
       } else if (Cand->IsSurrogate) {
         // Desugar the type of the surrogate down to a function type,

Modified: cfe/trunk/lib/Sema/SemaOverload.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.h?rev=82596&r1=82595&r2=82596&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.h (original)
+++ cfe/trunk/lib/Sema/SemaOverload.h Tue Sep 22 19:58:07 2009
@@ -195,7 +195,11 @@
       /// details of the user-defined conversion sequence.
       UserDefinedConversionSequence UserDefined;
     };
-
+    
+    /// When ConversionKind == BadConversion due to multiple conversion
+    /// functions, this will list those functions.
+    llvm::SmallVector<FunctionDecl*, 4> ConversionFunctionSet;
+    
     // The result of a comparison between implicit conversion
     // sequences. Use Sema::CompareImplicitConversionSequences to
     // actually perform the comparison.

Modified: cfe/trunk/test/SemaCXX/ambig-user-defined-convesions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/ambig-user-defined-convesions.cpp?rev=82596&r1=82595&r2=82596&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/ambig-user-defined-convesions.cpp (original)
+++ cfe/trunk/test/SemaCXX/ambig-user-defined-convesions.cpp Tue Sep 22 19:58:07 2009
@@ -1,10 +1,10 @@
 // RUN: clang-cc -fsyntax-only -verify %s
 
 struct BASE { 
-  operator int &(); // expected-note {{candidate function}}
+  operator int &(); // expected-note 4 {{candidate function}}
 }; 
 struct BASE1 { 
-  operator int &(); // expected-note {{candidate function}}
+  operator int &(); // expected-note 4 {{candidate function}}
 }; 
 
 struct B : public BASE, BASE1 { 
@@ -13,7 +13,14 @@
 
 extern B f(); 
 
+B b1;
+void func(const int ci, const char cc); // expected-note {{function not viable because of ambiguity in conversion of argument 1}}
+void func(const char ci, const B b); // expected-note {{function not viable because of ambiguity in conversion of argument 1}}
+void func(const B b, const int ci); // expected-note {{function not viable because of ambiguity in conversion of argument 2}}
+
+
 const int main() {
+  func(b1, f()); // expected-error {{no matching function for call to 'func'}}
   return f(); // expected-error {{conversion from 'struct B' to 'int const' is ambiguous}}
 }
 





More information about the cfe-commits mailing list