From: Patrick Palka Date: Wed, 3 Feb 2016 20:14:43 +0000 (+0000) Subject: Fix PR c++/69056 (argument pack deduction failure during overload resolution) X-Git-Tag: basepoints/gcc-7~1137 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ab4bae0c13ef8574defab12befd8af9545e5b32f;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 804deb068efa..6ac9a6482716 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 27dfdf863c3a..9cde9c738f6f 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 5bee4474de79..1a17a9de3376 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 000000000000..ab4e071b1b56 --- /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" } +}