Fix PR c++/69056 (argument pack deduction failure during overload resolution)

gcc/cp/ChangeLog:

	PR c++/69056
	* pt.c (try_one_overload): Handle comparing argument packs so
	that there is no conflict if we deduced more arguments of an
	argument pack than were explicitly specified.

gcc/testsuite/ChangeLog:

	PR c++/69056
	g++.dg/cpp0x/pr69056.C: New test.

From-SVN: r233108
This commit is contained in:
Patrick Palka 2016-02-03 20:14:43 +00:00
parent 95831c01a2
commit ab4bae0c13
4 changed files with 64 additions and 0 deletions

View file

@ -1,3 +1,10 @@
2016-02-03 Patrick Palka <ppalka@gcc.gnu.org>
PR c++/69056
* pt.c (try_one_overload): Handle comparing argument packs so
that there is no conflict if we deduced more arguments of an
argument pack than were explicitly specified.
2016-01-31 Jakub Jelinek <jakub@redhat.com>
Jason Merrill <jason@redhat.com>

View file

@ -18736,6 +18736,28 @@ try_one_overload (tree tparms,
template args used in the function parm list with our own
template parms. Discard them. */
TREE_VEC_ELT (tempargs, i) = NULL_TREE;
else if (oldelt && ARGUMENT_PACK_P (oldelt))
{
/* Check that the argument at each index of the deduced argument pack
is equivalent to the corresponding explicitly specified argument.
We may have deduced more arguments than were explicitly specified,
and that's OK. */
gcc_assert (ARGUMENT_PACK_INCOMPLETE_P (oldelt));
gcc_assert (ARGUMENT_PACK_ARGS (oldelt)
== ARGUMENT_PACK_EXPLICIT_ARGS (oldelt));
tree explicit_pack = ARGUMENT_PACK_ARGS (oldelt);
tree deduced_pack = ARGUMENT_PACK_ARGS (elt);
if (TREE_VEC_LENGTH (deduced_pack)
< TREE_VEC_LENGTH (explicit_pack))
return 0;
for (int j = 0; j < TREE_VEC_LENGTH (explicit_pack); j++)
if (!template_args_equal (TREE_VEC_ELT (explicit_pack, j),
TREE_VEC_ELT (deduced_pack, j)))
return 0;
}
else if (oldelt && !template_args_equal (oldelt, elt))
return 0;
}

View file

@ -1,3 +1,8 @@
2016-02-03 Patrick Palka <ppalka@gcc.gnu.org>
PR c++/69056
g++.dg/cpp0x/pr69056.C: New test.
2016-02-03 Vladimir Makarov <vmakarov@redhat.com>
Alexandre Oliva <aoliva@redhat.com>

View file

@ -0,0 +1,30 @@
// { dg-do compile { target c++11 } }
// PR c++/69056
template <typename T, typename... Args>
void resolver(int (*) (T, Args...));
int funcA(int, float) { return 0; }
int funcA(double) { return 0; }
int funcB(int, float, char) { return 0; }
int funcB(int, bool) { return 0; }
int funcB(double) { return 0; }
int funcC(int) { return 0; }
int funcC(double) { return 0; }
void
foo (void)
{
resolver (&funcA); // { dg-error "no match" }
resolver<int> (&funcA);
resolver<double> (&funcA);
resolver<int> (&funcB); // { dg-error "no match" }
resolver<int, char> (&funcB); // { dg-error "no match" }
resolver<int, float> (&funcB);
resolver<int> (&funcC);
resolver<int, float> (&funcC); // { dg-error "no match" }
}