]> granicus.if.org Git - clang/commitdiff
[Sema] Fix a bug where pack expansion was not expanded in type alias
authorErik Pilkington <erik.pilkington@gmail.com>
Tue, 5 Jul 2016 17:57:24 +0000 (17:57 +0000)
committerErik Pilkington <erik.pilkington@gmail.com>
Tue, 5 Jul 2016 17:57:24 +0000 (17:57 +0000)
The problem is that the parameter pack in a function type type alias is not
reexpanded after being transformed. Also remove an incorrect comment in a
similar function. Fixes PR26017.

Differential Revision: http://reviews.llvm.org/D21030

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

lib/Sema/TreeTransform.h
test/CXX/temp/temp.decls/temp.variadic/p5.cpp

index b13dc34377d0701d16042ec5143f2fcd06eb7734..88acc20600aada3c50ecaf03b188dc6242ae4bdb 100644 (file)
@@ -3327,8 +3327,6 @@ bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
         if (Out.isInvalid())
           return true;
 
-        // FIXME: Can this happen? We should not try to expand the pack
-        // in this case.
         if (Out.get()->containsUnexpandedParameterPack()) {
           Out = getDerived().RebuildPackExpansion(
               Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
@@ -4822,6 +4820,14 @@ bool TreeTransform<Derived>::TransformFunctionTypeParams(
           if (NewType.isNull())
             return true;
 
+          if (NewType->containsUnexpandedParameterPack()) {
+            NewType =
+                getSema().getASTContext().getPackExpansionType(NewType, None);
+
+            if (NewType.isNull())
+              return true;
+          }
+
           if (ParamInfos)
             PInfos.set(OutParamTypes.size(), ParamInfos[i]);
           OutParamTypes.push_back(NewType);
index 4f9368f6b6050ae74faf74b0fd4e15345863e88b..206e9f73e9f05f20560aa207b8bccb09c94350f7 100644 (file)
@@ -437,3 +437,35 @@ namespace PR21289 {
   template void g<>();
   template void g<1, 2, 3>();
 }
+
+template <class... Ts>
+int var_expr(Ts... ts);
+
+template <class... Ts>
+auto a_function(Ts... ts) -> decltype(var_expr(ts...));
+
+template <class T>
+using partial = decltype(a_function<int, T>);
+
+int use_partial() { partial<char> n; }
+
+namespace PR26017 {
+template <class T>
+struct Foo {};
+template <class... Ts>
+using FooAlias = Foo<void(Ts...)>;
+
+template <class... Ts>
+using FooAliasAlias = FooAlias<Ts..., Ts...>;
+
+template <class... Ts>
+void bar(const FooAlias<Ts...> &) {}
+
+int fn() {
+  FooAlias<> a;
+  bar(a);
+
+  FooAlias<int> b;
+  bar(b);
+}
+}