Index: lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- lib/Sema/SemaTemplateDeduction.cpp +++ lib/Sema/SemaTemplateDeduction.cpp @@ -2800,6 +2800,19 @@ // argument, because it was explicitly-specified. Just record the // presence of this argument. Builder.push_back(Deduced[I]); + // We may have had explicitly-specified template arguments for a + // template parameter pack (that may or may not have been extended + // via additional deduced arguments). + if (Param->isParameterPack() && CurrentInstantiationScope) { + const TemplateArgument *ExplicitArgs; + unsigned NumExplicitArgs; + if (CurrentInstantiationScope->getPartiallySubstitutedPack(&ExplicitArgs, + &NumExplicitArgs) == Param) { + // Forget the partially-substituted pack; it's substitution is now + // complete. + CurrentInstantiationScope->ResetPartiallySubstitutedPack(); + } + } continue; } Index: test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp =================================================================== --- test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp +++ test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp @@ -0,0 +1,80 @@ +// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -emit-llvm-only %s +// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING +// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS +// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING + +namespace explicit_argument_variadics { + + +template void print(Ts ... ) { } + +struct X { }; +struct Y { }; +struct Z { }; + +int test() { + { + auto L = [](auto ... as) { }; + L.operator()(true); + } + { + auto L = [](auto a) { }; + L.operator()(false); + } + { + auto L = [](auto a, auto b) { }; + L.operator()(false, 'a'); + } + { + auto L = [](auto a, auto b) { }; + L.operator()(false, 'a'); + } + { + auto L = [](auto a, auto b, auto ... cs) { }; + L.operator()(false, 'a'); + L.operator()(false, 'a', "jim"); + } + + { + auto L = [](auto ... As) { + }; + L.operator()(false, 3.14, "abc"); + } + { + auto L = [](auto A, auto B, auto ... As) { + }; + L.operator()(false, 3.14, "abc"); + L.operator()(false, 3.14, "abc"); //expected-warning{{implicit conversion}} + L.operator()(X{}, Y{}, 3.14, Z{}, X{}); //expected-warning{{implicit conversion}} + } + { + auto L = [](auto ... As) { + print("\nL::As = ", As ...); + return [](decltype(As) ... as, auto ... Bs) { + print("\nL::Inner::as = ", as ...); + print("\nL::Inner::Bs = ", Bs ...); + return 4; + }; + }; + auto M = L.operator()(false, 3.14, "abc"); + M(false, 6.26, "jim", true); + M.operator()(true, 6.26, "jim", false, 3.14); + } + { + auto L = [](auto A, auto ... As) { + print("\nL::As = ", As ...); + return [](decltype(As) ... as, decltype(A) a, auto ... Bs) { + print("\nL::Inner::as = ", as ...); + print("\nL::Inner::Bs = ", Bs ...); + return 4; + }; + }; + auto M = L.operator()(false, 3.14, "abc"); + M(6.26, "jim", true); + M.operator()(6.26, "jim", false, X{}, Y{}, Z{}); + } + + return 0; +} + int run = test(); +} // end ns explicit_argument_extension \ No newline at end of file