r300805 - PR32673: Don't wrap parameter packs in SubstTemplateTypeParmPackType nodes when forming implicit deduction guides.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 19 18:15:32 PDT 2017


Author: rsmith
Date: Wed Apr 19 20:15:31 2017
New Revision: 300805

URL: http://llvm.org/viewvc/llvm-project?rev=300805&view=rev
Log:
PR32673: Don't wrap parameter packs in SubstTemplateTypeParmPackType nodes when forming implicit deduction guides.

Doing so thwarts template type deduction. Instead, substitute the pack directly
by picking "slice 0" of the resulting expansion.

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

Modified: cfe/trunk/include/clang/AST/TypeLoc.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=300805&r1=300804&r2=300805&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Wed Apr 19 20:15:31 2017
@@ -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 :

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=300805&r1=300804&r2=300805&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Apr 19 20:15:31 2017
@@ -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;
 

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=300805&r1=300804&r2=300805&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp Wed Apr 19 20:15:31 2017
@@ -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);
+}




More information about the cfe-commits mailing list