Index: cp/pt.c =================================================================== --- cp/pt.c (revision 133641) +++ cp/pt.c (working copy) @@ -9916,9 +9916,30 @@ tsubst_copy (tree t, tree args, tsubst_f /* We only want to compute the number of arguments. */ tree expanded = tsubst_pack_expansion (TREE_OPERAND (t, 0), args, complain, in_decl); + int len; + + if (TREE_CODE (expanded) == TREE_VEC) + len = TREE_VEC_LENGTH (expanded); + if (expanded == error_mark_node) return error_mark_node; - return build_int_cst (size_type_node, TREE_VEC_LENGTH (expanded)); + else if (PACK_EXPANSION_P (expanded) + || (TREE_CODE (expanded) == TREE_VEC + && len > 0 + && PACK_EXPANSION_P (TREE_VEC_ELT (expanded, len-1)))) + { + if (TREE_CODE (expanded) == TREE_VEC) + expanded = TREE_VEC_ELT (expanded, len - 1); + + if (TYPE_P (expanded)) + return cxx_sizeof_or_alignof_type (expanded, SIZEOF_EXPR, + complain & tf_error); + else + return cxx_sizeof_or_alignof_expr (expanded, SIZEOF_EXPR, + complain & tf_error); + } + else + return build_int_cst (size_type_node, len); } /* Fall through */ @@ -10918,14 +10939,7 @@ tsubst_copy_and_build (tree t, case SIZEOF_EXPR: if (PACK_EXPANSION_P (TREE_OPERAND (t, 0))) - { - /* We only want to compute the number of arguments. */ - tree expanded = tsubst_pack_expansion (TREE_OPERAND (t, 0), args, - complain, in_decl); - if (expanded == error_mark_node) - return error_mark_node; - return build_int_cst (size_type_node, TREE_VEC_LENGTH (expanded)); - } + return tsubst_copy (t, args, complain, in_decl); /* Fall through */ case ALIGNOF_EXPR: Index: cp/parser.c =================================================================== --- cp/parser.c (revision 133641) +++ cp/parser.c (working copy) @@ -9435,29 +9435,41 @@ cp_parser_template_parameter (cp_parser* maybe_warn_variadic_templates (); *is_parameter_pack = true; + } + /* We might end up with a pack expansion as the type of the non-type + template parameter, in which case this is a non-type template + parameter pack. */ + else if (parameter_declarator + && parameter_declarator->decl_specifiers.type + && PACK_EXPANSION_P (parameter_declarator->decl_specifiers.type)) + { + *is_parameter_pack = true; + parameter_declarator->decl_specifiers.type = + PACK_EXPANSION_PATTERN (parameter_declarator->decl_specifiers.type); + } + if (*is_parameter_pack && cp_lexer_next_token_is (parser->lexer, CPP_EQ)) + { /* Parameter packs cannot have default arguments. However, a user may try to do so, so we'll parse them and give an appropriate diagnostic here. */ - if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)) - { - /* Consume the `='. */ - cp_lexer_consume_token (parser->lexer); - /* Find the name of the parameter pack. */ - id_declarator = parameter_declarator->declarator; - while (id_declarator && id_declarator->kind != cdk_id) - id_declarator = id_declarator->declarator; - - if (id_declarator && id_declarator->kind == cdk_id) - error ("template parameter pack %qD cannot have a default argument", - id_declarator->u.id.unqualified_name); - else - error ("template parameter pack cannot have a default argument"); - - /* Parse the default argument, but throw away the result. */ - cp_parser_default_argument (parser, /*template_parm_p=*/true); - } + /* Consume the `='. */ + cp_lexer_consume_token (parser->lexer); + + /* Find the name of the parameter pack. */ + id_declarator = parameter_declarator->declarator; + while (id_declarator && id_declarator->kind != cdk_id) + id_declarator = id_declarator->declarator; + + if (id_declarator && id_declarator->kind == cdk_id) + error ("template parameter pack %qD cannot have a default argument", + id_declarator->u.id.unqualified_name); + else + error ("template parameter pack cannot have a default argument"); + + /* Parse the default argument, but throw away the result. */ + cp_parser_default_argument (parser, /*template_parm_p=*/true); } parm = grokdeclarator (parameter_declarator->declarator, Index: testsuite/g++.dg/cpp0x/variadic91.C =================================================================== --- testsuite/g++.dg/cpp0x/variadic91.C (revision 0) +++ testsuite/g++.dg/cpp0x/variadic91.C (revision 0) @@ -0,0 +1,17 @@ +// { dg-options "-std=c++0x" } +template struct Int2Type { }; + +template +struct Outer { + template + void foo(Int2Type, Int2Type); +}; + + +Outer outer; + +void g4() { + outer.foo(Int2Type<3>(), Int2Type<2>()); +} + +template class X> void f1();