Skip to content

Commit

Permalink
[Sema] Fix a bug where pack expansion was not expanded in type alias
Browse files Browse the repository at this point in the history
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

llvm-svn: 274566
  • Loading branch information
epilk committed Jul 5, 2016
1 parent 2a15ffa commit f1bd000
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
10 changes: 8 additions & 2 deletions clang/lib/Sema/TreeTransform.h
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
32 changes: 32 additions & 0 deletions clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
Expand Up @@ -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);
}
}

0 comments on commit f1bd000

Please sign in to comment.