Skip to content
Snippets Groups Projects
Commit 770a04d6 authored by Richard Smith's avatar Richard Smith
Browse files

Fix conversion index / argument index mismatch when diagnosing overload resolution failure.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@291596 91177308-0d34-0410-b5e6-96231b3b80d8
parent e4ffc9c6
No related branches found
No related tags found
No related merge requests found
......@@ -10490,56 +10490,42 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,
// operation somehow.
bool SuppressUserConversions = false;
 
const FunctionProtoType *Proto;
unsigned ArgIdx = 0;
unsigned ConvIdx = 0;
ArrayRef<QualType> ParamTypes;
 
if (Cand->IsSurrogate) {
QualType ConvType
= Cand->Surrogate->getConversionType().getNonReferenceType();
if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
ConvType = ConvPtrType->getPointeeType();
Proto = ConvType->getAs<FunctionProtoType>();
ArgIdx = 1;
ParamTypes = ConvType->getAs<FunctionProtoType>()->getParamTypes();
// Conversion 0 is 'this', which doesn't have a corresponding argument.
ConvIdx = 1;
} else if (Cand->Function) {
Proto = Cand->Function->getType()->getAs<FunctionProtoType>();
ParamTypes =
Cand->Function->getType()->getAs<FunctionProtoType>()->getParamTypes();
if (isa<CXXMethodDecl>(Cand->Function) &&
!isa<CXXConstructorDecl>(Cand->Function))
ArgIdx = 1;
!isa<CXXConstructorDecl>(Cand->Function)) {
// Conversion 0 is 'this', which doesn't have a corresponding argument.
ConvIdx = 1;
}
} else {
// Builtin binary operator with a bad first conversion.
// Builtin operator.
assert(ConvCount <= 3);
for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0);
ConvIdx != ConvCount; ++ConvIdx) {
if (Cand->Conversions[ConvIdx].isInitialized())
continue;
if (Cand->BuiltinTypes.ParamTypes[ConvIdx]->isDependentType())
Cand->Conversions[ConvIdx].setAsIdentityConversion(
Args[ConvIdx]->getType());
else
Cand->Conversions[ConvIdx] = TryCopyInitialization(
S, Args[ConvIdx], Cand->BuiltinTypes.ParamTypes[ConvIdx],
SuppressUserConversions,
/*InOverloadResolution*/ true,
/*AllowObjCWritebackConversion=*/
S.getLangOpts().ObjCAutoRefCount);
// FIXME: If the conversion is bad, try to fix it.
}
return;
ParamTypes = Cand->BuiltinTypes.ParamTypes;
}
 
// Fill in the rest of the conversions.
unsigned NumParams = Proto->getNumParams();
for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0);
ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) {
for (unsigned ArgIdx = 0; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) {
if (Cand->Conversions[ConvIdx].isInitialized()) {
// Found the bad conversion.
} else if (ArgIdx < NumParams) {
if (Proto->getParamType(ArgIdx)->isDependentType())
// We've already checked this conversion.
} else if (ArgIdx < ParamTypes.size()) {
if (ParamTypes[ArgIdx]->isDependentType())
Cand->Conversions[ConvIdx].setAsIdentityConversion(
Args[ArgIdx]->getType());
else {
Cand->Conversions[ConvIdx] =
TryCopyInitialization(S, Args[ArgIdx], Proto->getParamType(ArgIdx),
TryCopyInitialization(S, Args[ArgIdx], ParamTypes[ArgIdx],
SuppressUserConversions,
/*InOverloadResolution=*/true,
/*AllowObjCWritebackConversion=*/
......
......@@ -383,6 +383,12 @@ namespace deduction_after_explicit_pack {
template<typename... T> struct X { X(int); operator int(); };
template<typename... T> void p(T..., X<T...>, ...); // expected-note {{deduced conflicting}}
void q() { p(X<int>(0), 0); } // expected-error {{no match}}
struct A {
template <typename T> void f(T, void *, int = 0); // expected-note {{no known conversion from 'double' to 'void *' for 2nd argument}}
void f(); // expected-note {{requires 0}}
};
void f(A a) { a.f(1.0, 2.0); } // expected-error {{no match}}
}
namespace overload_vs_pack {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment