r295710 - Fix lookup through injected-class-names in implicit deduction guides in the

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 21 00:42:40 PST 2017


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}}
 }




More information about the cfe-commits mailing list