From: Douglas Gregor Date: Mon, 3 Jan 2011 21:37:45 +0000 (+0000) Subject: Properly rebuild pack expansions whose pattern is a non-type template X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7a21fd45d4f04643cbfb5df96a01f84bc6d3dd14;p=clang Properly rebuild pack expansions whose pattern is a non-type template argument. As part of this, be more careful when determining if there are any parameter packs that cannot be expanded. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122776 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index c3cfbb8c25..1835899e80 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -3937,7 +3937,7 @@ static bool CheckNonTypeClassTemplatePartialSpecializationArgs(Sema &S, continue; } - // We can have a pack expansion of any of the above. + // We can have a pack expansion of any of the bullets below. if (PackExpansionExpr *Expansion = dyn_cast(ArgExpr)) ArgExpr = Expansion->getPattern(); diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index 828d2a3539..a3e308fe11 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -428,7 +428,8 @@ bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, // If we don't have a template argument at this depth/index, then we // cannot expand the pack expansion. Make a note of this, but we still // want to check any parameter packs we *do* have arguments for. - if (!TemplateArgs.hasTemplateArgument(Depth, Index)) { + if (Depth >= TemplateArgs.getNumLevels() || + !TemplateArgs.hasTemplateArgument(Depth, Index)) { ShouldExpand = false; continue; } diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 9088ae0fef..c38902a3e9 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -2102,11 +2102,18 @@ public: TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern, SourceLocation EllipsisLoc) { switch (Pattern.getArgument().getKind()) { - case TemplateArgument::Expression: - // FIXME: We should be able to handle this now! + case TemplateArgument::Expression: { + ExprResult Result + = getSema().ActOnPackExpansion(Pattern.getSourceExpression(), + EllipsisLoc); + if (Result.isInvalid()) + return TemplateArgumentLoc(); + + return TemplateArgumentLoc(Result.get(), Result.get()); + } case TemplateArgument::Template: - llvm_unreachable("Unsupported pack expansion of expressions/templates"); + llvm_unreachable("Unsupported pack expansion of templates"); case TemplateArgument::Null: case TemplateArgument::Integral: 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 new file mode 100644 index 0000000000..649c9b8ef2 --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +template struct value_tuple {}; + +template +struct X0 { + template + void f(value_tuple * = 0); +}; + +void test_X0() { + X0().f<1, 2, 3, 4, 5>(); +} diff --git a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp index d52d9c52a4..729a6a0bb2 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp @@ -212,7 +212,6 @@ struct TestUnexpandedDecls : T{ // FIXME: Test for unexpanded parameter packs in each of the statements. // Test unexpanded parameter packs in partial specializations. - template struct TestUnexpandedDecls; // expected-error{{partial specialization contains unexpanded parameter pack 'Types'}}