From 150a4989ecf988595f80809abf84835c9625b33c Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Fri, 6 Jun 2014 17:33:35 +0000 Subject: [PATCH] Retain an expression pack expansion when the parameter pack expansion code asks us to. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@210355 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/TreeTransform.h | 29 ++++++++++++++++++++++++++-- test/SemaTemplate/pack-deduction.cpp | 7 +++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 94b2e959df..eba23a5def 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -2912,9 +2912,11 @@ bool TreeTransform::TransformExprs(Expr **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 = RebuildPackExpansion(Out.get(), Expansion->getEllipsisLoc(), - OrigNumExpansions); + Out = getDerived().RebuildPackExpansion( + Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions); if (Out.isInvalid()) return true; } @@ -2922,6 +2924,23 @@ bool TreeTransform::TransformExprs(Expr **Inputs, Outputs.push_back(Out.get()); } + // If we're supposed to retain a pack expansion, do so by temporarily + // forgetting the partially-substituted parameter pack. + if (RetainExpansion) { + ForgetPartiallySubstitutedPackRAII Forget(getDerived()); + + ExprResult Out = getDerived().TransformExpr(Pattern); + if (Out.isInvalid()) + return true; + + Out = getDerived().RebuildPackExpansion( + Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions); + if (Out.isInvalid()) + return true; + + Outputs.push_back(Out.get()); + } + continue; } @@ -8618,6 +8637,9 @@ TreeTransform::TransformLambdaScope(LambdaExpr *E, // Capture the transformed variable. getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind); } + + // FIXME: Retain a pack expansion if RetainExpansion is true. + continue; } @@ -9122,6 +9144,7 @@ TreeTransform::TransformObjCDictionaryLiteral( // If any unexpanded parameter packs remain, we still have a // pack expansion. + // FIXME: Can this really happen? if (Key.get()->containsUnexpandedParameterPack() || Value.get()->containsUnexpandedParameterPack()) Element.EllipsisLoc = OrigElement.EllipsisLoc; @@ -9129,6 +9152,8 @@ TreeTransform::TransformObjCDictionaryLiteral( Elements.push_back(Element); } + // FIXME: Retain a pack expansion if RetainExpansion is true. + // We've finished with this pack expansion. continue; } diff --git a/test/SemaTemplate/pack-deduction.cpp b/test/SemaTemplate/pack-deduction.cpp index abb76de693..f3f969e9af 100644 --- a/test/SemaTemplate/pack-deduction.cpp +++ b/test/SemaTemplate/pack-deduction.cpp @@ -30,3 +30,10 @@ namespace PR14841 { f(a); // expected-error {{no matching function}} } } + +namespace RetainExprPacks { + int f(int a, int b, int c); + template struct X {}; + template int g(X, decltype(f(Ts()...))); + int n = g(X(), 0); +} -- 2.50.1