]> granicus.if.org Git - clang/commitdiff
PR32673: Don't wrap parameter packs in SubstTemplateTypeParmPackType nodes when formi...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 20 Apr 2017 01:15:31 +0000 (01:15 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 20 Apr 2017 01:15:31 +0000 (01:15 +0000)
Doing so thwarts template type deduction. Instead, substitute the pack directly
by picking "slice 0" of the resulting expansion.

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

include/clang/AST/TypeLoc.h
lib/Sema/SemaTemplate.cpp
test/SemaCXX/cxx1z-class-template-argument-deduction.cpp

index 525f848a9fab7494be41c04ac6bae5e3415e5f4b..ad95f6f8effaa87cc30b4121374f263da79075a7 100644 (file)
@@ -1544,7 +1544,11 @@ class DependentSizedArrayTypeLoc :
     public InheritingConcreteTypeLoc<ArrayTypeLoc,
                                      DependentSizedArrayTypeLoc,
                                      DependentSizedArrayType> {
-
+public:
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+    ArrayTypeLoc::initializeLocal(Context, Loc);
+    setSizeExpr(getTypePtr()->getSizeExpr());
+  }
 };
 
 class VariableArrayTypeLoc :
index f522e76b0673ba298ae79beba0f9d314f8f55896..61b4df40964c618eb338f358c972acbbaa75fbf3 100644 (file)
@@ -1636,11 +1636,22 @@ private:
   transformFunctionTypeParam(ParmVarDecl *OldParam,
                              MultiLevelTemplateArgumentList &Args) {
     TypeSourceInfo *OldDI = OldParam->getTypeSourceInfo();
-    TypeSourceInfo *NewDI =
-        Args.getNumLevels()
-            ? SemaRef.SubstType(OldDI, Args, OldParam->getLocation(),
-                                OldParam->getDeclName())
-            : OldDI;
+    TypeSourceInfo *NewDI;
+    if (!Args.getNumLevels())
+      NewDI = OldDI;
+    else if (auto PackTL = OldDI->getTypeLoc().getAs<PackExpansionTypeLoc>()) {
+      // Expand out the one and only element in each inner pack.
+      Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, 0);
+      NewDI =
+          SemaRef.SubstType(PackTL.getPatternLoc(), Args,
+                            OldParam->getLocation(), OldParam->getDeclName());
+      if (!NewDI) return nullptr;
+      NewDI =
+          SemaRef.CheckPackExpansion(NewDI, PackTL.getEllipsisLoc(),
+                                     PackTL.getTypePtr()->getNumExpansions());
+    } else
+      NewDI = SemaRef.SubstType(OldDI, Args, OldParam->getLocation(),
+                                OldParam->getDeclName());
     if (!NewDI)
       return nullptr;
 
index d6374e4ce90754d175dc8c8a890b5f20780226e0..5de228ad2857455b3ddec2a9ff9a8e4797e541d3 100644 (file)
@@ -213,3 +213,38 @@ namespace transform_params {
   };
   D d(Y<0, 1, 2>{});
 }
+
+namespace variadic {
+  int arr3[3], arr4[4];
+
+  // PR32673
+  template<typename T> struct A {
+    template<typename ...U> A(T, U...);
+  };
+  A a(1, 2, 3);
+
+  template<typename T> struct B {
+    template<int ...N> B(T, int (&...r)[N]);
+  };
+  B b(1, arr3, arr4);
+
+  template<typename T> struct C {
+    template<template<typename> typename ...U> C(T, U<int>...);
+  };
+  C c(1, a, b);
+
+  template<typename ...U> struct X {
+    template<typename T> X(T, U...);
+  };
+  X x(1, 2, 3);
+
+  template<int ...N> struct Y {
+    template<typename T> Y(T, int (&...r)[N]);
+  };
+  Y y(1, arr3, arr4);
+
+  template<template<typename> typename ...U> struct Z {
+    template<typename T> Z(T, U<int>...);
+  };
+  Z z(1, a, b);
+}