diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-10-12 17:51:19 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-10-12 17:51:19 +0000 |
commit | 27687cf7f6fea50e592f653549a33f07bf5c0667 (patch) | |
tree | 82256494992ff19e9455eb575f7ed3d67ce70a8e /lib/Sema/SemaOverload.cpp | |
parent | 1555c3a3b36043e14f2d4d839cfd5b8f2df0f9e5 (diff) |
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*();
^
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83862 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 30ac59e4ca..27d34ef434 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -464,7 +464,8 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType, 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 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet, 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 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet, << 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 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, 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); } |