[PATCH] D21030: [Sema] Fix rejects-valid where parameter pack was not expanded in type alias
Erik Pilkington via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 6 09:52:19 PDT 2016
erik.pilkington created this revision.
erik.pilkington added a reviewer: rsmith.
erik.pilkington added a subscriber: cfe-commits.
Clang rejects the following valid code:
```
template <class T> struct Foo {};
template <class... Ts> using FooAlias = Foo<void(Ts...)>;
template <class... Ts> int bar(FooAlias<Ts...>);
int main() { bar(FooAlias<>()); }
```
The problem is that in the substitution of `FooAlias<Ts...>` during the parsing of bar, the pack expansion in `Foo<void(Ts...)>` is transformed into a parameter with the unexpanded flag set, as opposed to another pack expansion. This leads to deduction failing in `main`, which is incorrect. The fix is to expand the parameter pack when needed.
Fixes PR25250 & PR26017.
Incidentally, there was an incorrect comment in a very similar function that said that a path wasn't reachable. This isn't the case, although no existing test case exercised it, so I added one that did. Please let me know if it would be cleaner to commit that separately!
Thanks!
http://reviews.llvm.org/D21030
Files:
lib/Sema/TreeTransform.h
test/CXX/temp/temp.decls/temp.variadic/p5.cpp
Index: test/CXX/temp/temp.decls/temp.variadic/p5.cpp
===================================================================
--- test/CXX/temp/temp.decls/temp.variadic/p5.cpp
+++ test/CXX/temp/temp.decls/temp.variadic/p5.cpp
@@ -437,3 +437,32 @@
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>
+void bar(const FooAlias<Ts...> &) {}
+
+int fn() {
+ FooAlias<> a;
+ bar(a);
+
+ FooAlias<int> b;
+ bar(b);
+}
+}
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -3311,8 +3311,6 @@
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);
@@ -4781,6 +4779,13 @@
if (NewType.isNull())
return true;
+ if (NewType->containsUnexpandedParameterPack()) {
+ NewType = getDerived().RebuildPackExpansionType(
+ NewType, SourceRange(), Loc, NumExpansions);
+ if (NewType.isNull())
+ return true;
+ }
+
if (ParamInfos)
PInfos.set(OutParamTypes.size(), ParamInfos[i]);
OutParamTypes.push_back(NewType);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D21030.59682.patch
Type: text/x-patch
Size: 1813 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160606/7c1932dd/attachment.bin>
More information about the cfe-commits
mailing list