From: Paolo Carlini Date: Wed, 30 Jul 2014 20:06:29 +0000 (+0000) Subject: re PR c++/57397 (Off-by-one error in diagnostic when calling variadic function templa... X-Git-Tag: releases/gcc-5.1.0~5898 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5b9802c45c2c0cfe93d261518e5ca466197cbf8f;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 25d9b8acb321..f01020776200 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 0eac7718b221..33a8bf47151b 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 d0e5f2611456..629e89e6df2d 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 000000000000..1d9a1e076192 --- /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 000000000000..d217008fbfeb --- /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); +}