From 5b9802c45c2c0cfe93d261518e5ca466197cbf8f Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Wed, 30 Jul 2014 20:06:29 +0000 Subject: [PATCH] re PR c++/57397 (Off-by-one error in diagnostic when calling variadic function template with too few arguments) /cp 2014-07-30 Paolo Carlini PR c++/57397 * pt.c (unify_arity): Add boolean parameter. (unify_too_few_arguments): Likewise. (type_unification_real): Diagnose correctly insufficient arguments in the presence of trailing variadic parameters; deducing multiple trailing packs as empty is fine. /testsuite 2014-07-30 Paolo Carlini PR c++/57397 * g++.dg/cpp0x/vt-57397-1.C: New. * g++.dg/cpp0x/vt-57397-2.C: Likewise. From-SVN: r213310 --- gcc/cp/ChangeLog | 9 ++++++ gcc/cp/pt.c | 39 ++++++++++++++++++------- gcc/testsuite/ChangeLog | 7 ++++- gcc/testsuite/g++.dg/cpp0x/vt-57397-1.C | 22 ++++++++++++++ gcc/testsuite/g++.dg/cpp0x/vt-57397-2.C | 24 +++++++++++++++ 5 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/vt-57397-1.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/vt-57397-2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 25d9b8acb32..f0102077620 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2014-07-30 Paolo Carlini + + PR c++/57397 + * pt.c (unify_arity): Add boolean parameter. + (unify_too_few_arguments): Likewise. + (type_unification_real): Diagnose correctly insufficient + arguments in the presence of trailing variadic parameters; + deducing multiple trailing packs as empty is fine. + 2014-07-30 Jason Merrill PR c++/61659 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 0eac7718b22..33a8bf47151 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5527,13 +5527,21 @@ unify_method_type_error (bool explain_p, tree arg) } static int -unify_arity (bool explain_p, int have, int wanted) +unify_arity (bool explain_p, int have, int wanted, bool least_p = false) { if (explain_p) - inform_n (input_location, wanted, - " candidate expects %d argument, %d provided", - " candidate expects %d arguments, %d provided", - wanted, have); + { + if (least_p) + inform_n (input_location, wanted, + " candidate expects at least %d argument, %d provided", + " candidate expects at least %d arguments, %d provided", + wanted, have); + else + inform_n (input_location, wanted, + " candidate expects %d argument, %d provided", + " candidate expects %d arguments, %d provided", + wanted, have); + } return 1; } @@ -5544,9 +5552,10 @@ unify_too_many_arguments (bool explain_p, int have, int wanted) } static int -unify_too_few_arguments (bool explain_p, int have, int wanted) +unify_too_few_arguments (bool explain_p, int have, int wanted, + bool least_p = false) { - return unify_arity (explain_p, have, wanted); + return unify_arity (explain_p, have, wanted, least_p); } static int @@ -16627,18 +16636,26 @@ type_unification_real (tree tparms, are present, and the parm list isn't variadic. */ if (ia < nargs && parms == void_list_node) return unify_too_many_arguments (explain_p, nargs, ia); - /* Fail if parms are left and they don't have default values. */ + /* Fail if parms are left and they don't have default values and + they aren't all deduced as empty packs (c++/57397). This is + consistent with sufficient_parms_p. */ if (parms && parms != void_list_node && TREE_PURPOSE (parms) == NULL_TREE) { unsigned int count = nargs; tree p = parms; - while (p && p != void_list_node) + bool type_pack_p; + do { - count++; + type_pack_p = TREE_CODE (TREE_VALUE (p)) == TYPE_PACK_EXPANSION; + if (!type_pack_p) + count++; p = TREE_CHAIN (p); } - return unify_too_few_arguments (explain_p, ia, count); + while (p && p != void_list_node); + if (count != nargs) + return unify_too_few_arguments (explain_p, ia, count, + type_pack_p); } if (!subr) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d0e5f261145..629e89e6df2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-07-30 Paolo Carlini + + PR c++/57397 + * g++.dg/cpp0x/vt-57397-1.C: New. + * g++.dg/cpp0x/vt-57397-2.C: Likewise. + 2014-07-30 Arnaud Charlet * gnat.dg/case_null.adb, gnat.dg/specs/debug1.ads: Adjust tests. @@ -11,7 +17,6 @@ * g++.dg/ipa/devirt-34.C: New testcase. ->>>>>>> .r213302 2014-07-28 Richard Biener PR rtl-optimization/61801 diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-57397-1.C b/gcc/testsuite/g++.dg/cpp0x/vt-57397-1.C new file mode 100644 index 00000000000..1d9a1e07619 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/vt-57397-1.C @@ -0,0 +1,22 @@ +// PR c++/57397 +// { dg-do compile { target c++11 } } + +template +void foo(T1, Tn...); + +template +void bar(T1, T2, Tn...); + +int main() +{ + foo(); // { dg-error "no matching" } + // { dg-message "candidate expects at least 1 argument, 0 provided" "" { target *-*-* } 12 } + foo(1); + foo(1, 2); + bar(); // { dg-error "no matching" } + // { dg-message "candidate expects at least 2 arguments, 0 provided" "" { target *-*-* } 16 } + bar(1); // { dg-error "no matching" } + // { dg-message "candidate expects at least 2 arguments, 1 provided" "" { target *-*-* } 18 } + bar(1, 2); + bar(1, 2, 3); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-57397-2.C b/gcc/testsuite/g++.dg/cpp0x/vt-57397-2.C new file mode 100644 index 00000000000..d217008fbfe --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/vt-57397-2.C @@ -0,0 +1,24 @@ +// PR c++/57397 +// { dg-do compile { target c++11 } } + +template +void foo(T1, Tn..., Tm...); + +template +void bar(T1, T2, Tn..., Tm...); + +int main() +{ + foo(); // { dg-error "no matching" } + // { dg-message "candidate expects at least 1 argument, 0 provided" "" { target *-*-* } 12 } + foo(1); + foo(1, 2); + foo(1, 2, 3); + bar(); // { dg-error "no matching" } + // { dg-message "candidate expects at least 2 arguments, 0 provided" "" { target *-*-* } 17 } + bar(1); // { dg-error "no matching" } + // { dg-message "candidate expects at least 2 arguments, 1 provided" "" { target *-*-* } 19 } + bar(1, 2); + bar(1, 2, 3); + bar(1, 2, 3, 4); +}