зеркало из https://github.com/microsoft/clang-1.git
Produce detailed diagnostics when overload
resolution failed to select a candidate due to ambiguity in type conversion function selection. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82596 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
d489cd06a1
Коммит
b1663d0507
|
@ -763,6 +763,8 @@ def err_ovl_ambiguous_member_call : Error<
|
|||
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<
|
||||
|
|
|
@ -411,13 +411,15 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
|
|||
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 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
|
|||
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 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
|
|||
*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,
|
||||
|
|
|
@ -195,7 +195,11 @@ namespace clang {
|
|||
/// 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.
|
||||
|
|
|
@ -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 @@ struct B : public BASE, BASE1 {
|
|||
|
||||
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}}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче