aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-10-10 18:59:29 +0000
committerDouglas Gregor <dgregor@apple.com>2011-10-10 18:59:29 +0000
commit089e8939b7b3e72c32477e39df82f18e6a8f436e (patch)
treedc6fc026836bae79337bce363c3db64b82ec9b18
parent30aa95140a1bc19e3e57795c788fb5b4f5921ad7 (diff)
When substituting into a sizeof parameter pack expression in a context
where we can't expand (i.e., multi-level substitution), be sure to substitute the pack with its level-reduced pack. Fixes PR10230. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141568 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/TreeTransform.h24
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp15
2 files changed, 34 insertions, 5 deletions
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 33aaf92d81..2a18afafd9 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -2140,10 +2140,15 @@ public:
ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
SourceLocation PackLoc,
SourceLocation RParenLoc,
- unsigned Length) {
+ llvm::Optional<unsigned> Length) {
+ if (Length)
+ return new (SemaRef.Context) SizeOfPackExpr(SemaRef.Context.getSizeType(),
+ OperatorLoc, Pack, PackLoc,
+ RParenLoc, *Length);
+
return new (SemaRef.Context) SizeOfPackExpr(SemaRef.Context.getSizeType(),
OperatorLoc, Pack, PackLoc,
- RParenLoc, Length);
+ RParenLoc);
}
/// \brief Build a new Objective-C @encode expression.
@@ -7709,14 +7714,23 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
NumExpansions))
return ExprError();
- if (!ShouldExpand || RetainExpansion)
+ if (RetainExpansion)
return SemaRef.Owned(E);
+
+ NamedDecl *Pack = E->getPack();
+ if (!ShouldExpand) {
+ Pack = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getPackLoc(),
+ Pack));
+ if (!Pack)
+ return ExprError();
+ }
+
// We now know the length of the parameter pack, so build a new expression
// that stores that length.
- return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
+ return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), Pack,
E->getPackLoc(), E->getRParenLoc(),
- *NumExpansions);
+ NumExpansions);
}
template<typename Derived>
diff --git a/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
index cda9ac8b04..22076fee98 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
@@ -234,3 +234,18 @@ namespace ExpandingFunctionParameters {
x1.f(17, 3.14159);
}
}
+
+namespace PR10230 {
+ template<typename>
+ struct s
+ {
+ template<typename... Args>
+ auto f() -> int(&)[sizeof...(Args)];
+ };
+
+ void main()
+ {
+ int (&ir1)[1] = s<int>().f<int>();
+ int (&ir3)[3] = s<int>().f<int, float, double>();
+ }
+}