--- gcc/cp/cp/pt.c.jj 2007-09-27 13:04:12.000000000 +0200 +++ gcc/cp/cp/pt.c 2007-09-27 13:52:20.000000000 +0200 @@ -12515,7 +12515,7 @@ unify (tree tparms, tree targs, tree par tree argvec = INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (arg)); tree argtmplvec = DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (arg)); - int i; + int i, j; /* The resolution to DR150 makes clear that default arguments for an N-argument may not be used to bind T @@ -12557,11 +12557,55 @@ unify (tree tparms, tree targs, tree par rather than the whole TREE_VEC since they can have different number of elements. */ - for (i = 0; i < TREE_VEC_LENGTH (parmvec); ++i) + for (i = 0, j = 0; i < TREE_VEC_LENGTH (parmvec); ++i, ++j) { + if (j >= TREE_VEC_LENGTH (argvec)) + return 1; + + if (ARGUMENT_PACK_P (TREE_VEC_ELT (parmvec, i)) + && !ARGUMENT_PACK_P (TREE_VEC_ELT (argvec, i))) + { + tree packed_parms + = ARGUMENT_PACK_ARGS (TREE_VEC_ELT (parmvec, i)); + int len = TREE_VEC_LENGTH (packed_parms); + int parm_variadic_p = 0; + int argslen = TREE_VEC_LENGTH (argvec) - j; + int k; + + /* Check if the parameters end in a pack, + making them variadic. */ + if (len > 0 + && PACK_EXPANSION_P (TREE_VEC_ELT (packed_parms, + len - 1))) + parm_variadic_p = 1; + + if (parm_variadic_p && i != TREE_VEC_LENGTH (parmvec) - 1) + return 1; + + /* If we don't have enough arguments to satisfy the + parameters, we can't unify. */ + if (argslen < (len - parm_variadic_p)) + return 1; + + /* Unify all of the parameters that precede the (optional) + pack expression. */ + for (k = 0; k < len - parm_variadic_p; k++) + if (unify (tparms, targs, TREE_VEC_ELT (packed_parms, k), + TREE_VEC_ELT (argvec, j + k), + UNIFY_ALLOW_NONE)) + return 1; + + j += k - 1; + + if (parm_variadic_p) + return 1; /* FIXME */ + + continue; + } + if (unify (tparms, targs, TREE_VEC_ELT (parmvec, i), - TREE_VEC_ELT (argvec, i), + TREE_VEC_ELT (argvec, j), UNIFY_ALLOW_NONE)) return 1; } @@ -12980,6 +13024,8 @@ unify (tree tparms, tree targs, tree par case TYPE_ARGUMENT_PACK: case NONTYPE_ARGUMENT_PACK: + if (TREE_CODE (parm) != TREE_CODE (arg)) + return 1; { tree packed_parms = ARGUMENT_PACK_ARGS (parm); tree packed_args = ARGUMENT_PACK_ARGS (arg); --- gcc/cp/testsuite/g++.dg/cpp0x/variadic79.C.jj 2007-09-27 14:03:06.000000000 +0200 +++ gcc/cp/testsuite/g++.dg/cpp0x/variadic79.C 2007-09-27 14:02:01.000000000 +0200 @@ -0,0 +1,26 @@ +// PR c++/32565 +// { dg-do compile } +// { dg-options "-std=c++0x" } + +template struct A1; +template class T> struct A1 > {}; +template struct A2; +template class T> struct A2 > {}; +template struct A3; +template class T> struct A3 > {}; +template struct A4; +template class T> struct A4 > {}; +template struct A5; +template class T> struct A5 > {}; +template struct A6; +template class T> struct A6 > {}; +template struct B1 {}; +template struct B2 {}; +template struct B3 {}; +template struct B4 {}; +A1 > a1; +A2 > a2; +A3 > a3; +A4 > a4; +A5 > a5; +A6 > a6;