forked from OSchip/llvm-project
Improve overload-candidate diagnostic for a function template that
failed because the explicitly-specified template arguments did not match its template parameters, e.g., test/SemaTemplate/overload-candidates.cpp:18:8: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'I' void get(const T&); ^ test/SemaTemplate/overload-candidates.cpp:20:8: note: candidate template ignored: invalid explicitly-specified argument for 1st template parameter void get(const T&); ^ llvm-svn: 103344
This commit is contained in:
parent
564767cf39
commit
1d72edd7c5
|
@ -1063,7 +1063,13 @@ def note_ovl_candidate_incomplete_deduction : Note<"candidate template ignored:
|
|||
def note_ovl_candidate_inconsistent_deduction : Note<
|
||||
"candidate template ignored: deduced conflicting %select{types|values|"
|
||||
"templates}0 for parameter %1 (%2 vs. %3)">;
|
||||
|
||||
def note_ovl_candidate_explicit_arg_mismatch_named : Note<
|
||||
"candidate template ignored: invalid explicitly-specified argument "
|
||||
"for template parameter %0">;
|
||||
def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note<
|
||||
"candidate template ignored: invalid explicitly-specified argument "
|
||||
"for %ordinal0 template parameter">;
|
||||
|
||||
// Note that we don't treat templates differently for this diagnostic.
|
||||
def note_ovl_candidate_arity : Note<"candidate "
|
||||
"%select{function|function|constructor|function|function|constructor|"
|
||||
|
|
|
@ -301,6 +301,7 @@ static MakeDeductionFailureInfo(Sema::TemplateDeductionResult TDK,
|
|||
break;
|
||||
|
||||
case Sema::TDK_Incomplete:
|
||||
case Sema::TDK_InvalidExplicitArguments:
|
||||
Result.Data = Info.Param.getOpaqueValue();
|
||||
break;
|
||||
|
||||
|
@ -316,7 +317,6 @@ static MakeDeductionFailureInfo(Sema::TemplateDeductionResult TDK,
|
|||
|
||||
case Sema::TDK_SubstitutionFailure:
|
||||
case Sema::TDK_NonDeducedMismatch:
|
||||
case Sema::TDK_InvalidExplicitArguments:
|
||||
case Sema::TDK_FailedOverloadResolution:
|
||||
break;
|
||||
}
|
||||
|
@ -331,6 +331,7 @@ void OverloadCandidate::DeductionFailureInfo::Destroy() {
|
|||
case Sema::TDK_Incomplete:
|
||||
case Sema::TDK_TooManyArguments:
|
||||
case Sema::TDK_TooFewArguments:
|
||||
case Sema::TDK_InvalidExplicitArguments:
|
||||
break;
|
||||
|
||||
case Sema::TDK_Inconsistent:
|
||||
|
@ -342,7 +343,6 @@ void OverloadCandidate::DeductionFailureInfo::Destroy() {
|
|||
// Unhandled
|
||||
case Sema::TDK_SubstitutionFailure:
|
||||
case Sema::TDK_NonDeducedMismatch:
|
||||
case Sema::TDK_InvalidExplicitArguments:
|
||||
case Sema::TDK_FailedOverloadResolution:
|
||||
break;
|
||||
}
|
||||
|
@ -358,6 +358,7 @@ OverloadCandidate::DeductionFailureInfo::getTemplateParameter() {
|
|||
return TemplateParameter();
|
||||
|
||||
case Sema::TDK_Incomplete:
|
||||
case Sema::TDK_InvalidExplicitArguments:
|
||||
return TemplateParameter::getFromOpaqueValue(Data);
|
||||
|
||||
case Sema::TDK_Inconsistent:
|
||||
|
@ -367,7 +368,6 @@ OverloadCandidate::DeductionFailureInfo::getTemplateParameter() {
|
|||
// Unhandled
|
||||
case Sema::TDK_SubstitutionFailure:
|
||||
case Sema::TDK_NonDeducedMismatch:
|
||||
case Sema::TDK_InvalidExplicitArguments:
|
||||
case Sema::TDK_FailedOverloadResolution:
|
||||
break;
|
||||
}
|
||||
|
@ -382,6 +382,7 @@ const TemplateArgument *OverloadCandidate::DeductionFailureInfo::getFirstArg() {
|
|||
case Sema::TDK_Incomplete:
|
||||
case Sema::TDK_TooManyArguments:
|
||||
case Sema::TDK_TooFewArguments:
|
||||
case Sema::TDK_InvalidExplicitArguments:
|
||||
return 0;
|
||||
|
||||
case Sema::TDK_Inconsistent:
|
||||
|
@ -391,7 +392,6 @@ const TemplateArgument *OverloadCandidate::DeductionFailureInfo::getFirstArg() {
|
|||
// Unhandled
|
||||
case Sema::TDK_SubstitutionFailure:
|
||||
case Sema::TDK_NonDeducedMismatch:
|
||||
case Sema::TDK_InvalidExplicitArguments:
|
||||
case Sema::TDK_FailedOverloadResolution:
|
||||
break;
|
||||
}
|
||||
|
@ -407,6 +407,7 @@ OverloadCandidate::DeductionFailureInfo::getSecondArg() {
|
|||
case Sema::TDK_Incomplete:
|
||||
case Sema::TDK_TooManyArguments:
|
||||
case Sema::TDK_TooFewArguments:
|
||||
case Sema::TDK_InvalidExplicitArguments:
|
||||
return 0;
|
||||
|
||||
case Sema::TDK_Inconsistent:
|
||||
|
@ -416,7 +417,6 @@ OverloadCandidate::DeductionFailureInfo::getSecondArg() {
|
|||
// Unhandled
|
||||
case Sema::TDK_SubstitutionFailure:
|
||||
case Sema::TDK_NonDeducedMismatch:
|
||||
case Sema::TDK_InvalidExplicitArguments:
|
||||
case Sema::TDK_FailedOverloadResolution:
|
||||
break;
|
||||
}
|
||||
|
@ -425,6 +425,12 @@ OverloadCandidate::DeductionFailureInfo::getSecondArg() {
|
|||
}
|
||||
|
||||
void OverloadCandidateSet::clear() {
|
||||
//
|
||||
for (iterator C = begin(), CEnd = end(); C != CEnd; ++C) {
|
||||
if (C->FailureKind == ovl_fail_bad_deduction)
|
||||
C->DeductionFailure.Destroy();
|
||||
}
|
||||
|
||||
inherited::clear();
|
||||
Functions.clear();
|
||||
}
|
||||
|
@ -5086,15 +5092,15 @@ void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand,
|
|||
FunctionDecl *Fn = Cand->Function; // pattern
|
||||
|
||||
TemplateParameter Param = Cand->DeductionFailure.getTemplateParameter();
|
||||
NamedDecl *ParamD;
|
||||
(ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()) ||
|
||||
(ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()) ||
|
||||
(ParamD = Param.dyn_cast<TemplateTemplateParmDecl*>());
|
||||
switch (Cand->DeductionFailure.Result) {
|
||||
case Sema::TDK_Success:
|
||||
llvm_unreachable("TDK_success while diagnosing bad deduction");
|
||||
|
||||
case Sema::TDK_Incomplete: {
|
||||
NamedDecl *ParamD;
|
||||
(ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()) ||
|
||||
(ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()) ||
|
||||
(ParamD = Param.dyn_cast<TemplateTemplateParmDecl*>());
|
||||
assert(ParamD && "no parameter found for incomplete deduction result");
|
||||
S.Diag(Fn->getLocation(), diag::note_ovl_candidate_incomplete_deduction)
|
||||
<< ParamD->getDeclName();
|
||||
|
@ -5103,14 +5109,13 @@ void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand,
|
|||
|
||||
case Sema::TDK_Inconsistent:
|
||||
case Sema::TDK_InconsistentQuals: {
|
||||
NamedDecl *ParamD;
|
||||
assert(ParamD && "no parameter found for inconsistent deduction result");
|
||||
int which = 0;
|
||||
if ((ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()))
|
||||
if (isa<TemplateTypeParmDecl>(ParamD))
|
||||
which = 0;
|
||||
else if ((ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()))
|
||||
else if (isa<NonTypeTemplateParmDecl>(ParamD))
|
||||
which = 1;
|
||||
else {
|
||||
ParamD = Param.get<TemplateTemplateParmDecl*>();
|
||||
which = 2;
|
||||
}
|
||||
|
||||
|
@ -5121,6 +5126,27 @@ void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand,
|
|||
return;
|
||||
}
|
||||
|
||||
case Sema::TDK_InvalidExplicitArguments:
|
||||
assert(ParamD && "no parameter found for invalid explicit arguments");
|
||||
if (ParamD->getDeclName())
|
||||
S.Diag(Fn->getLocation(),
|
||||
diag::note_ovl_candidate_explicit_arg_mismatch_named)
|
||||
<< ParamD->getDeclName();
|
||||
else {
|
||||
int index = 0;
|
||||
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ParamD))
|
||||
index = TTP->getIndex();
|
||||
else if (NonTypeTemplateParmDecl *NTTP
|
||||
= dyn_cast<NonTypeTemplateParmDecl>(ParamD))
|
||||
index = NTTP->getIndex();
|
||||
else
|
||||
index = cast<TemplateTemplateParmDecl>(ParamD)->getIndex();
|
||||
S.Diag(Fn->getLocation(),
|
||||
diag::note_ovl_candidate_explicit_arg_mismatch_unnamed)
|
||||
<< (index + 1);
|
||||
}
|
||||
return;
|
||||
|
||||
case Sema::TDK_TooManyArguments:
|
||||
case Sema::TDK_TooFewArguments:
|
||||
DiagnoseArityMismatch(S, Cand, NumArgs);
|
||||
|
@ -5131,7 +5157,6 @@ void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand,
|
|||
case Sema::TDK_InstantiationDepth:
|
||||
case Sema::TDK_SubstitutionFailure:
|
||||
case Sema::TDK_NonDeducedMismatch:
|
||||
case Sema::TDK_InvalidExplicitArguments:
|
||||
case Sema::TDK_FailedOverloadResolution:
|
||||
S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_deduction);
|
||||
return;
|
||||
|
|
|
@ -1190,8 +1190,11 @@ Sema::SubstituteExplicitTemplateArguments(
|
|||
SourceLocation(),
|
||||
ExplicitTemplateArgs,
|
||||
true,
|
||||
Builder) || Trap.hasErrorOccurred())
|
||||
Builder) || Trap.hasErrorOccurred()) {
|
||||
Info.Param = makeTemplateParameter(TemplateParams->getParam(
|
||||
Builder.structuredSize()));
|
||||
return TDK_InvalidExplicitArguments;
|
||||
}
|
||||
|
||||
// Form the template argument list from the explicitly-specified
|
||||
// template arguments.
|
||||
|
|
|
@ -6,3 +6,19 @@ const T& min(const T&, const T&); // expected-note{{candidate template ignored:
|
|||
void test_min() {
|
||||
(void)min(1, 2l); // expected-error{{no matching function for call to 'min'}}
|
||||
}
|
||||
|
||||
template<typename R, typename T>
|
||||
R *dyn_cast(const T&); // expected-note{{candidate template ignored: couldn't infer template argument 'R'}}
|
||||
|
||||
void test_dyn_cast(int* ptr) {
|
||||
(void)dyn_cast(ptr); // expected-error{{no matching function for call to 'dyn_cast'}}
|
||||
}
|
||||
|
||||
template<int I, typename T>
|
||||
void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for template parameter 'I'}}
|
||||
template<template<class T> class, typename T>
|
||||
void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
|
||||
|
||||
void test_get(void *ptr) {
|
||||
get<int>(ptr); // expected-error{{no matching function for call to 'get'}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue