diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-10-10 18:59:29 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-10-10 18:59:29 +0000 |
commit | ab96bcf6ea1d29ee06a34014a23ca7e9675773d7 (patch) | |
tree | eea3809f94d8719d14d93a47f1394a3eef5b9f26 | |
parent | ba0bc4f522a26c77110f1b2c94571e03dac29d69 (diff) | |
download | bcm5719-llvm-ab96bcf6ea1d29ee06a34014a23ca7e9675773d7.tar.gz bcm5719-llvm-ab96bcf6ea1d29ee06a34014a23ca7e9675773d7.zip |
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.
llvm-svn: 141568
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 24 | ||||
-rw-r--r-- | clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp | 15 |
2 files changed, 34 insertions, 5 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 33aaf92d813..2a18afafd9b 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/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/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp index cda9ac8b045..22076fee989 100644 --- a/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp +++ b/clang/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>(); + } +} |