]> granicus.if.org Git - clang/commitdiff
PR42362: Fix auto deduction of template parameter packs from
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 24 Jun 2019 05:53:11 +0000 (05:53 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 24 Jun 2019 05:53:11 +0000 (05:53 +0000)
type-dependent argument packs.

We need to strip off the PackExpansionExpr to get the real (dependent)
type rather than an opaque DependentTy.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@364165 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplate.cpp
test/SemaTemplate/temp_arg_nontype_cxx1z.cpp

index 7b0a3a3e094cfba06371ec4a12e3de01edae9f8e..49ba771379e17b8488e7a36e3339858343929add 100644 (file)
@@ -6323,9 +6323,12 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
     // the type is dependent, in order to check the types of non-type template
     // arguments line up properly in partial ordering.
     Optional<unsigned> Depth = Param->getDepth() + 1;
+    Expr *DeductionArg = Arg;
+    if (auto *PE = dyn_cast<PackExpansionExpr>(DeductionArg))
+      DeductionArg = PE->getPattern();
     if (DeduceAutoType(
             Context.getTrivialTypeSourceInfo(ParamType, Param->getLocation()),
-            Arg, ParamType, Depth) == DAR_Failed) {
+            DeductionArg, ParamType, Depth) == DAR_Failed) {
       Diag(Arg->getExprLoc(),
            diag::err_non_type_template_parm_type_deduction_failure)
         << Param->getDeclName() << Param->getType() << Arg->getType()
index b887c7f47d3cf636d8e3d1bce0281203de287513..d73a88777d0c80489461162b1776f0ea99b71a2b 100644 (file)
@@ -378,3 +378,18 @@ template <class T> struct M {
   }
 };
 }
+
+namespace PR42362 {
+  template<auto ...A> struct X { struct Y; void f(int...[A]); };
+  template<auto ...A> struct X<A...>::Y {};
+  template<auto ...A> void X<A...>::f(int...[A]) {}
+  void f() { X<1, 2>::Y y; X<1, 2>().f(0, 0); }
+
+  template<typename, auto...> struct Y;
+  template<auto ...A> struct Y<int, A...> {};
+  Y<int, 1, 2, 3> y;
+
+  template<auto (&...F)()> struct Z { struct Q; };
+  template<auto (&...F)()> struct Z<F...>::Q {};
+  Z<f, f, f>::Q q;
+}