Author: rsmith Date: Tue Feb 21 02:42:39 2017 New Revision: 295710 URL: http://llvm.org/viewvc/llvm-project?rev=295710&view=rev Log: Fix lookup through injected-class-names in implicit deduction guides in the case where the class template has a parameter pack.
Checking of the template arguments expects an "as-written" template argument list, which in particular does not have any parameter packs. So flatten the packs into separate arguments before passing them in. Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=295710&r1=295709&r2=295710&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Feb 21 02:42:39 2017 @@ -4957,11 +4957,17 @@ NamedDecl *Sema::FindInstantiatedDecl(So auto *Guide = dyn_cast<CXXDeductionGuideDecl>(FD); if (Guide && Guide->isImplicit()) { TemplateDecl *TD = Guide->getDeducedTemplate(); + // Convert the arguments to an "as-written" list. TemplateArgumentListInfo Args(Loc, Loc); - for (auto Arg : TemplateArgs.getInnermost().take_front( - TD->getTemplateParameters()->size())) - Args.addArgument( - getTrivialTemplateArgumentLoc(Arg, QualType(), Loc)); + for (TemplateArgument Arg : TemplateArgs.getInnermost().take_front( + TD->getTemplateParameters()->size())) { + ArrayRef<TemplateArgument> Unpacked(Arg); + if (Arg.getKind() == TemplateArgument::Pack) + Unpacked = Arg.pack_elements(); + for (TemplateArgument UnpackedArg : Unpacked) + Args.addArgument( + getTrivialTemplateArgumentLoc(UnpackedArg, QualType(), Loc)); + } QualType T = CheckTemplateIdType(TemplateName(TD), Loc, Args); if (T.isNull()) return nullptr; Modified: cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp?rev=295710&r1=295709&r2=295710&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp Tue Feb 21 02:42:39 2017 @@ -194,9 +194,22 @@ namespace transform_params { A a(qn, qn); // expected-error {{no matching constructor for initialization of 'transform_params::A<int, 12, Q, &transform_params::n>'}} static_assert(a.v == 12); - // FIXME: This should be accepted. - template<typename ...T> struct B { // expected-note {{candidate}} - template<T ...V> B(const T (&...p)[V]); // expected-note {{substitution failure}} + template<typename ...T> struct B { + template<T ...V> B(const T (&...p)[V]) { + constexpr int Vs[] = {V...}; + static_assert(Vs[0] == 3 && Vs[1] == 4 && Vs[2] == 4); + } + static constexpr int (*p)(T...) = (int(*)(int, char, char))nullptr; }; - B b({1, 2, 3}, {"foo", "bar"}, {'x', 'y', 'z', 'w'}); // expected-error {{no viable constructor or deduction guide}} + B b({1, 2, 3}, "foo", {'x', 'y', 'z', 'w'}); // ok + + template<typename ...T> struct C { // expected-note {{candidate}} + template<T ...V, template<T...> typename X> + C(X<V...>); // expected-note {{substitution failure [with T = <>, V = <0, 1, 2>]}} + }; + template<int...> struct Y {}; + // FIXME: This incorrectly deduces T = <>, rather than deducing + // T = <int, int, int> from the types of the elements of V. + // (This failure is not related to class template argument deduction.) + C c(Y<0, 1, 2>{}); // expected-error {{no viable constructor or deduction guide}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits