aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-05-08 19:15:54 +0000
committerDouglas Gregor <dgregor@apple.com>2010-05-08 19:15:54 +0000
commitf1a8445036a2d047c7165d4170e3058cdeaba6eb (patch)
treefb7e6495091f1c263821ff171b0c33028739a4dc
parenta95342c9d4209379c07ac8da553688eacf500f98 (diff)
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&); ^ git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103344 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td8
-rw-r--r--lib/Sema/SemaOverload.cpp53
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp5
-rw-r--r--test/SemaTemplate/overload-candidates.cpp16
4 files changed, 66 insertions, 16 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index f0901d246b..235ac86a22 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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|"
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 136183a0ac..f738236133 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -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;
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 2bb97eba11..f716ccd6f7 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -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.
diff --git a/test/SemaTemplate/overload-candidates.cpp b/test/SemaTemplate/overload-candidates.cpp
index 84e23716a9..936a6d7aaf 100644
--- a/test/SemaTemplate/overload-candidates.cpp
+++ b/test/SemaTemplate/overload-candidates.cpp
@@ -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'}}
+}