From: Jason Merrill Date: Mon, 26 Jun 2017 18:49:18 +0000 (-0400) Subject: PR c++/81215 - deduction failure with variadic TTP. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b0d1023d5f5f52a21d00f6e7eb5d46898c052171;p=gcc.git PR c++/81215 - deduction failure with variadic TTP. * pt.c (unify_bound_ttp_args): Restore old logic for C++14 and down. From-SVN: r249664 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8bc268c1dcd..c067d23eb8a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2017-06-26 Jason Merrill + + PR c++/81215 - deduction failure with variadic TTP. + * pt.c (unify_bound_ttp_args): Restore old logic for C++14 and down. + 2017-06-26 Martin Sebor PR c++/81169 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 392fba07714..43f9ca8b39e 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7170,26 +7170,68 @@ unify_bound_ttp_args (tree tparms, tree targs, tree parm, tree& arg, parmvec = expand_template_argument_pack (parmvec); argvec = expand_template_argument_pack (argvec); - tree nparmvec = parmvec; if (flag_new_ttp) { /* In keeping with P0522R0, adjust P's template arguments to apply to A's template; then flatten it again. */ + tree nparmvec = parmvec; nparmvec = coerce_ttp_args_for_tta (arg, parmvec, tf_none); nparmvec = expand_template_argument_pack (nparmvec); - } - if (unify (tparms, targs, nparmvec, argvec, - UNIFY_ALLOW_NONE, explain_p)) - return 1; + if (unify (tparms, targs, nparmvec, argvec, + UNIFY_ALLOW_NONE, explain_p)) + return 1; - /* If the P0522 adjustment eliminated a pack expansion, deduce - empty packs. */ - if (flag_new_ttp - && TREE_VEC_LENGTH (nparmvec) < TREE_VEC_LENGTH (parmvec) - && unify_pack_expansion (tparms, targs, parmvec, argvec, - DEDUCE_EXACT, /*sub*/true, explain_p)) - return 1; + /* If the P0522 adjustment eliminated a pack expansion, deduce + empty packs. */ + if (flag_new_ttp + && TREE_VEC_LENGTH (nparmvec) < TREE_VEC_LENGTH (parmvec) + && unify_pack_expansion (tparms, targs, parmvec, argvec, + DEDUCE_EXACT, /*sub*/true, explain_p)) + return 1; + } + else + { + /* Deduce arguments T, i from TT or TT. + We check each element of PARMVEC and ARGVEC individually + rather than the whole TREE_VEC since they can have + different number of elements, which is allowed under N2555. */ + + int len = TREE_VEC_LENGTH (parmvec); + + /* Check if the parameters end in a pack, making them + variadic. */ + int parm_variadic_p = 0; + if (len > 0 + && PACK_EXPANSION_P (TREE_VEC_ELT (parmvec, len - 1))) + parm_variadic_p = 1; + + for (int i = 0; i < len - parm_variadic_p; ++i) + /* If the template argument list of P contains a pack + expansion that is not the last template argument, the + entire template argument list is a non-deduced + context. */ + if (PACK_EXPANSION_P (TREE_VEC_ELT (parmvec, i))) + return unify_success (explain_p); + + if (TREE_VEC_LENGTH (argvec) < len - parm_variadic_p) + return unify_too_few_arguments (explain_p, + TREE_VEC_LENGTH (argvec), len); + + for (int i = 0; i < len - parm_variadic_p; ++i) + if (unify (tparms, targs, + TREE_VEC_ELT (parmvec, i), + TREE_VEC_ELT (argvec, i), + UNIFY_ALLOW_NONE, explain_p)) + return 1; + + if (parm_variadic_p + && unify_pack_expansion (tparms, targs, + parmvec, argvec, + DEDUCE_EXACT, + /*subr=*/true, explain_p)) + return 1; + } return 0; } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ttp7.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp7.C new file mode 100644 index 00000000000..0dbe904601d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp7.C @@ -0,0 +1,16 @@ +// PR c++/81215 +// { dg-do compile { target c++11 } } + +template struct X { }; +template struct set { }; + +template class C> +void bar (const X>&) +{ +} + +void +foo (X>& x) +{ + bar (x); +}