diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -1337,6 +1337,13 @@ TemplateDeductionInfo &Info, SmallVectorImpl &Deduced, unsigned TDF, bool PartialOrdering, bool DeducedFromArrayBound) { + + // If the argument type is a pack expansion, look at its pattern. + // This isn't explicitly called out + if (const auto *AExp = dyn_cast(A)) + A = AExp->getPattern(); + assert(!isa(A.getCanonicalType())); + if (PartialOrdering) { // C++11 [temp.deduct.partial]p5: // Before the partial ordering is done, certain transformations are diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp --- a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -// expected-no-diagnostics // Note: Partial ordering of function templates containing template // parameter packs is independent of the number of deduced arguments @@ -26,3 +25,15 @@ double &dr1 = h((int(*)(int, float&))0); double &dr2 = h((int(*)(int))0); } + +namespace test_j { + +template struct ref {}; + +template void map(ref...); +template void map(ref x, ref... xs); // expected-note {{here}} + +template void map<0, 1>(ref<0>, ref<1>); +// expected-error@-1 {{explicit instantiation of undefined function template 'map'}} + +} // namespace test_j