summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaTemplate.cpp11
-rw-r--r--test/SemaTemplate/pack-deduction.cpp12
2 files changed, 23 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index d893c88110..d6ea3d0e2e 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -3856,6 +3856,17 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
++ArgIdx;
}
+ // If we're performing a partial argument substitution, allow any trailing
+ // pack expansions; they might be empty. This can happen even if
+ // PartialTemplateArgs is false (the list of arguments is complete but
+ // still dependent).
+ if (ArgIdx < NumArgs && CurrentInstantiationScope &&
+ CurrentInstantiationScope->getPartiallySubstitutedPack()) {
+ while (ArgIdx < NumArgs &&
+ TemplateArgs[ArgIdx].getArgument().isPackExpansion())
+ Converted.push_back(TemplateArgs[ArgIdx++].getArgument());
+ }
+
// If we have any leftover arguments, then there were too many arguments.
// Complain and fail.
if (ArgIdx < NumArgs)
diff --git a/test/SemaTemplate/pack-deduction.cpp b/test/SemaTemplate/pack-deduction.cpp
index 2d0a03f0fc..abb76de693 100644
--- a/test/SemaTemplate/pack-deduction.cpp
+++ b/test/SemaTemplate/pack-deduction.cpp
@@ -18,3 +18,15 @@ namespace Nested {
int b1 = f2(P<X<int, double>, int>(), P<X<int, double>, double>());
int b2 = f2(P<X<int, double>, int>(), P<X<int, double>, double>(), P<X<int, double>, char>()); // expected-error {{no matching}}
}
+
+namespace PR14841 {
+ template<typename T, typename U> struct A {};
+ template<typename ...Ts> void f(A<Ts...>); // expected-note {{substitution failure [with Ts = <char, short, int>]: too many template arg}}
+
+ void g(A<char, short> a) {
+ f(a);
+ f<char>(a);
+ f<char, short>(a);
+ f<char, short, int>(a); // expected-error {{no matching function}}
+ }
+}