From ab4bae0c13ef8574defab12befd8af9545e5b32f Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Wed, 3 Feb 2016 20:14:43 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/pt.c | 22 ++++++++++++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp0x/pr69056.C | 30 ++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/pr69056.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 804deb068ef..6ac9a648271 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2016-02-03 Patrick Palka + + 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 Jason Merrill diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 27dfdf863c3..9cde9c738f6 100644 --- a/gcc/cp/pt.c +++ b/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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5bee4474de7..1a17a9de337 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-02-03 Patrick Palka + + PR c++/69056 + g++.dg/cpp0x/pr69056.C: New test. + 2016-02-03 Vladimir Makarov Alexandre Oliva diff --git a/gcc/testsuite/g++.dg/cpp0x/pr69056.C b/gcc/testsuite/g++.dg/cpp0x/pr69056.C new file mode 100644 index 00000000000..ab4e071b1b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr69056.C @@ -0,0 +1,30 @@ +// { dg-do compile { target c++11 } } +// PR c++/69056 + +template +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 (&funcA); + resolver (&funcA); + + resolver (&funcB); // { dg-error "no match" } + resolver (&funcB); // { dg-error "no match" } + resolver (&funcB); + + resolver (&funcC); + resolver (&funcC); // { dg-error "no match" } +}