summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-07-19 19:00:37 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-07-19 19:00:37 +0000
commit4a8f3518cb1444f7041ecb36fceb49d59f08b4b1 (patch)
tree993ad7351ac668d1ff6fdefcfd17c49bdfc5d408 /clang/lib/Sema/SemaTemplate.cpp
parentf29044536d7a77cac152948a066c44e7cb010627 (diff)
downloadbcm5719-llvm-4a8f3518cb1444f7041ecb36fceb49d59f08b4b1.tar.gz
bcm5719-llvm-4a8f3518cb1444f7041ecb36fceb49d59f08b4b1.zip
Fix template argument deduction when a parameter pack has a value
provided by an outer template. We made the incorrect assumption in various places that the only way we can have any arguments already provided for a pack during template argument deduction was from a partially-specified pack. That's not true; we can also have arguments from an enclosing already-instantiated template, and that can even result in the function template's own pack parameters having a fixed length and not being packs for the purposes of template argument deduction. llvm-svn: 337481
Diffstat (limited to 'clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp45
1 files changed, 20 insertions, 25 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index c1d8c24796d..935264cb8cc 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -4914,27 +4914,6 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
return false;
}
-/// Diagnose an arity mismatch in the
-static bool diagnoseArityMismatch(Sema &S, TemplateDecl *Template,
- SourceLocation TemplateLoc,
- TemplateArgumentListInfo &TemplateArgs) {
- TemplateParameterList *Params = Template->getTemplateParameters();
- unsigned NumParams = Params->size();
- unsigned NumArgs = TemplateArgs.size();
-
- SourceRange Range;
- if (NumArgs > NumParams)
- Range = SourceRange(TemplateArgs[NumParams].getLocation(),
- TemplateArgs.getRAngleLoc());
- S.Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
- << (NumArgs > NumParams)
- << (int)S.getTemplateNameKindForDiagnostics(TemplateName(Template))
- << Template << Range;
- S.Diag(Template->getLocation(), diag::note_template_decl_here)
- << Params->getSourceRange();
- return true;
-}
-
/// Check whether the template parameter is a pack expansion, and if so,
/// determine the number of parameters produced by that expansion. For instance:
///
@@ -4988,7 +4967,15 @@ static bool diagnoseMissingArgument(Sema &S, SourceLocation Loc,
// FIXME: If there's a more recent default argument that *is* visible,
// diagnose that it was declared too late.
- return diagnoseArityMismatch(S, TD, Loc, Args);
+ TemplateParameterList *Params = TD->getTemplateParameters();
+
+ S.Diag(Loc, diag::err_template_arg_list_different_arity)
+ << /*not enough args*/0
+ << (int)S.getTemplateNameKindForDiagnostics(TemplateName(TD))
+ << TD;
+ S.Diag(TD->getLocation(), diag::note_template_decl_here)
+ << Params->getSourceRange();
+ return true;
}
/// Check that the given template argument list is well-formed
@@ -5040,7 +5027,7 @@ bool Sema::CheckTemplateArgumentList(
} else if (ArgIdx == NumArgs && !PartialTemplateArgs) {
// Not enough arguments for this parameter pack.
Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
- << false
+ << /*not enough args*/0
<< (int)getTemplateNameKindForDiagnostics(TemplateName(Template))
<< Template;
Diag(Template->getLocation(), diag::note_template_decl_here)
@@ -5235,8 +5222,16 @@ bool Sema::CheckTemplateArgumentList(
// If we have any leftover arguments, then there were too many arguments.
// Complain and fail.
- if (ArgIdx < NumArgs)
- return diagnoseArityMismatch(*this, Template, TemplateLoc, NewArgs);
+ if (ArgIdx < NumArgs) {
+ Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
+ << /*too many args*/1
+ << (int)getTemplateNameKindForDiagnostics(TemplateName(Template))
+ << Template
+ << SourceRange(NewArgs[ArgIdx].getLocation(), NewArgs.getRAngleLoc());
+ Diag(Template->getLocation(), diag::note_template_decl_here)
+ << Params->getSourceRange();
+ return true;
+ }
// No problems found with the new argument list, propagate changes back
// to caller.
OpenPOWER on IntegriCloud