re PR c++/81215 (deduction failure with variadic template template parameter)

PR c++/81215

	* pt.c (unify_bound_ttp_args): Restore old logic for C++14 and down.

From-SVN: r249665
This commit is contained in:
Jason Merrill 2017-06-26 14:49:25 -04:00 committed by Jason Merrill
parent e860a3fd7f
commit aa2978007a
3 changed files with 74 additions and 11 deletions

View File

@ -1,3 +1,8 @@
2017-06-26 Jason Merrill <jason@redhat.com>
PR c++/81215
* pt.c (unify_bound_ttp_args): Restore old logic for C++14 and down.
2017-06-23 Jason Merrill <jason@redhat.com>
PR c++/79056 - C++17 ICE with invalid template syntax.

View File

@ -7110,26 +7110,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 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<T> or TT<i>.
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. */
if (unify (tparms, targs, nparmvec, argvec,
UNIFY_ALLOW_NONE, explain_p))
return 1;
int len = TREE_VEC_LENGTH (parmvec);
/* 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;
/* 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;
}

View File

@ -0,0 +1,16 @@
// PR c++/81215
// { dg-do compile { target c++11 } }
template<typename U> struct X { };
template<typename T, typename U = void> struct set { };
template <typename V, template <typename...> class C>
void bar (const X<C<V>>&)
{
}
void
foo (X<set<int>>& x)
{
bar (x);
}