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:
parent
95831c01a2
commit
ab4bae0c13
4 changed files with 64 additions and 0 deletions
|
@ -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>
|
||||
|
||||
|
|
22
gcc/cp/pt.c
22
gcc/cp/pt.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
30
gcc/testsuite/g++.dg/cpp0x/pr69056.C
Normal file
30
gcc/testsuite/g++.dg/cpp0x/pr69056.C
Normal 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" }
|
||||
}
|
Loading…
Add table
Reference in a new issue