]> granicus.if.org Git - clang/commitdiff
Handle built-in unary operators when reporting ambiguities.
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 12 Oct 2009 20:11:40 +0000 (20:11 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 12 Oct 2009 20:11:40 +0000 (20:11 +0000)
wip - To prune excessive reporting.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83889 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/Sema.h
lib/Sema/SemaOverload.cpp
test/SemaCXX/ambiguous-builtin-unary-operator.cpp [new file with mode: 0644]

index b81278f037ce81da1dbdd6d1a2e32afeb6806e20..252cfd2718918f596b6b6ccb8ebd6ee1c6995f6b 100644 (file)
@@ -786,7 +786,10 @@ def err_ovl_template_candidate : Note<
   "candidate function template specialization %0">;
 def err_ovl_candidate_deleted : Note<
   "candidate function has been explicitly %select{made unavailable|deleted}0">;
-def err_ovl_builtin_candidate : Note<"built-in candidate operator %2 (%0, %1)">;
+def err_ovl_builtin_binary_candidate : Note<
+    "built-in candidate operator %0 (%1, %2)">;
+def err_ovl_builtin_unary_candidate : Note<
+    "built-in candidate operator %0 (%1)">;
 def err_ovl_no_viable_function_in_init : Error<
   "no matching constructor for initialization of %0">;
 def err_ovl_ambiguous_init : Error<"call to constructor of %0 is ambiguous">;
index a889eeefe8f27d00e588c9643d550609436e3e61..7b6fa47e28efc9e68c8f60f18b375bb07e39e946 100644 (file)
@@ -916,7 +916,7 @@ public:
                                        OverloadCandidateSet::iterator& Best);
   void PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
                          bool OnlyViable,
-                         BinaryOperator::Opcode Opc=(BinaryOperator::Opcode)0,
+                         const char *Opc=0,
                          SourceLocation Loc=SourceLocation());
 
   FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
index 27d34ef43459981b7fca76c8672c81256d087f55..7744ae7c59d1b9e5741c882c92c147a280fc923a 100644 (file)
@@ -3973,7 +3973,7 @@ Sema::BestViableFunction(OverloadCandidateSet& CandidateSet,
 void
 Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
                               bool OnlyViable,
-                              BinaryOperator::Opcode Opc,
+                              const char *Opc,
                               SourceLocation OpLoc) {
   OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
                              LastCand = CandidateSet.end();
@@ -4048,20 +4048,22 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
         Diag(Cand->Surrogate->getLocation(), diag::err_ovl_surrogate_cand)
           << FnType;
       } else if (OnlyViable) {
-        assert(Cand->Conversions.size() == 2 && 
+        assert(Cand->Conversions.size() <= 2 && 
                "builtin-binary-operator-not-binary");
-        Diag(OpLoc, diag::err_ovl_builtin_candidate) 
-          << Cand->BuiltinTypes.ParamTypes[0] 
-          << Cand->BuiltinTypes.ParamTypes[1] 
-          << BinaryOperator::getOpcodeStr(Opc);
+        if (Cand->Conversions.size() == 1)
+          Diag(OpLoc, diag::err_ovl_builtin_unary_candidate)
+                << Opc << Cand->BuiltinTypes.ParamTypes[0];
+        else
+          Diag(OpLoc, diag::err_ovl_builtin_binary_candidate)
+                << Opc << Cand->BuiltinTypes.ParamTypes[0]
+                << Cand->BuiltinTypes.ParamTypes[1];
       }
       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) {
+        unsigned NoOperands = Cand->Conversions.size();
+        for (unsigned ArgIdx = 0; ArgIdx < NoOperands; ++ArgIdx) {
           const ImplicitConversionSequence &ICS = Cand->Conversions[ArgIdx];
           if (ICS.ConversionKind != ImplicitConversionSequence::BadConversion ||
               ICS.ConversionFunctionSet.empty())
@@ -4559,7 +4561,8 @@ Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc,
       Diag(OpLoc,  diag::err_ovl_ambiguous_oper)
           << UnaryOperator::getOpcodeStr(Opc)
           << Input->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
+      PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true, 
+                              UnaryOperator::getOpcodeStr(Opc), OpLoc);
       return ExprError();
 
     case OR_Deleted:
@@ -4733,7 +4736,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
       assert(Result.isInvalid() && 
              "C++ binary operator overloading is missing candidates!");
       if (Result.isInvalid())
-        PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false, Opc, OpLoc);
+        PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false, 
+                                BinaryOperator::getOpcodeStr(Opc), OpLoc);
       return move(Result);
     }
 
@@ -4741,7 +4745,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
       Diag(OpLoc,  diag::err_ovl_ambiguous_oper)
           << BinaryOperator::getOpcodeStr(Opc)
           << Args[0]->getSourceRange() << Args[1]->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true, Opc, OpLoc);
+      PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true, 
+                              BinaryOperator::getOpcodeStr(Opc), OpLoc);
       return ExprError();
 
     case OR_Deleted:
diff --git a/test/SemaCXX/ambiguous-builtin-unary-operator.cpp b/test/SemaCXX/ambiguous-builtin-unary-operator.cpp
new file mode 100644 (file)
index 0000000..042546a
--- /dev/null
@@ -0,0 +1,18 @@
+// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x
+
+struct A {
+  operator int&();
+};
+
+struct B {
+  operator long&();
+};
+
+struct C : B, A { };
+
+void test(C c) {
+  ++c; // expected-error {{use of overloaded operator '++' is ambiguous}}\
+       // expected-note 4 {{built-in candidate operator ++ (}}
+}
+
+