[cfe-commits] r83862 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaOverload.cpp test/SemaCXX/builtin-ptrtomember-overload-1.cpp test/SemaCXX/decl-init-ref.cpp

Fariborz Jahanian fjahanian at apple.com
Mon Oct 12 10:51:20 PDT 2009


Author: fjahanian
Date: Mon Oct 12 12:51:19 2009
New Revision: 83862

URL: http://llvm.org/viewvc/llvm-project?rev=83862&view=rev
Log:
If built-in operators could not be selected because of ambiguity in
user-defined type conversions, issue list of ambiguites in addition 
to the diagnostic. So, clang now issues the following:

b.cpp:19:19: error: left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'struct C1'
        int i = c1->*pmf;
                ~~^
b.cpp:19:19: note: because of ambiguity in conversion of 'struct C1' to 'struct E *'
b.cpp:5:5: note: candidate function
    operator E*();
    ^
b.cpp:11:5: note: candidate function
    operator E*();
    ^

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
    cfe/trunk/test/SemaCXX/decl-init-ref.cpp

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

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Oct 12 12:51:19 2009
@@ -780,6 +780,8 @@
 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 note_ambiguous_type_conversion: Note<
+    "because of ambiguity in conversion of %0 to %1">;
 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=83862&r1=83861&r2=83862&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Oct 12 12:51:19 2009
@@ -464,7 +464,8 @@
     if (UserDefResult == OR_Ambiguous) {
       for (OverloadCandidateSet::iterator Cand = Conversions.begin();
            Cand != Conversions.end(); ++Cand)
-        ICS.ConversionFunctionSet.push_back(Cand->Function);
+        if (Cand->Viable)
+          ICS.ConversionFunctionSet.push_back(Cand->Function);
     }
   }
 
@@ -3976,6 +3977,7 @@
                               SourceLocation OpLoc) {
   OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
                              LastCand = CandidateSet.end();
+  bool Reported = false;
   for (; Cand != LastCand; ++Cand) {
     if (Cand->Viable || !OnlyViable) {
       if (Cand->Function) {
@@ -4053,6 +4055,33 @@
           << Cand->BuiltinTypes.ParamTypes[1] 
           << BinaryOperator::getOpcodeStr(Opc);
       }
+      else if (!Cand->Viable && !Reported) {
+        // Non-viability might be due to ambiguous user-defined conversions,
+        // needed for built-in operators. Report them as well, but only once
+        // as we have typically many built-in candidates.
+        assert(Cand->Conversions.size() == 2 &&
+               "builtin-binary-operator-not-binary");
+        for (unsigned ArgIdx = 0; ArgIdx < 2; ++ArgIdx) {
+          const ImplicitConversionSequence &ICS = Cand->Conversions[ArgIdx];
+          if (ICS.ConversionKind != ImplicitConversionSequence::BadConversion ||
+              ICS.ConversionFunctionSet.empty())
+            continue;
+          if (CXXConversionDecl *Func = dyn_cast<CXXConversionDecl>(
+                         Cand->Conversions[ArgIdx].ConversionFunctionSet[0])) {
+            QualType FromTy = 
+              QualType(
+                     static_cast<Type*>(ICS.UserDefined.Before.FromTypePtr),0);
+            Diag(OpLoc,diag::note_ambiguous_type_conversion)
+                  << FromTy << Func->getConversionType();
+          }
+          for (unsigned j = 0; j < ICS.ConversionFunctionSet.size(); j++) {
+            FunctionDecl *Func = 
+              Cand->Conversions[ArgIdx].ConversionFunctionSet[j];
+            Diag(Func->getLocation(),diag::err_ovl_candidate);
+          }
+        }
+        Reported = true;
+      }
     }
   }
 }
@@ -4704,7 +4733,7 @@
       assert(Result.isInvalid() && 
              "C++ binary operator overloading is missing candidates!");
       if (Result.isInvalid())
-        PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
+        PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false, Opc, OpLoc);
       return move(Result);
     }
 

Modified: cfe/trunk/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/builtin-ptrtomember-overload-1.cpp?rev=83862&r1=83861&r2=83862&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/builtin-ptrtomember-overload-1.cpp (original)
+++ cfe/trunk/test/SemaCXX/builtin-ptrtomember-overload-1.cpp Mon Oct 12 12:51:19 2009
@@ -5,13 +5,13 @@
 
 struct R {
     operator A*();
-    operator E*();
+    operator E*();	// expected-note{{candidate function}}
 };
 
 
 struct S {
     operator A*();
-    operator E*();
+    operator E*();	// expected-note{{candidate function}}
 };
 
 struct B  : R {
@@ -41,5 +41,6 @@
 
 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'}}
+        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 *'}}
 }

Modified: cfe/trunk/test/SemaCXX/decl-init-ref.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/decl-init-ref.cpp?rev=83862&r1=83861&r2=83862&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/decl-init-ref.cpp (original)
+++ cfe/trunk/test/SemaCXX/decl-init-ref.cpp Mon Oct 12 12:51:19 2009
@@ -1,6 +1,6 @@
 // RUN: clang-cc -fsyntax-only -verify -std=c++0x %s
 
-struct A {};    // expected-note {{candidate function}}
+struct A {};    
 
 struct BASE {
   operator A(); // expected-note {{candidate function}}





More information about the cfe-commits mailing list