From 1c89478aef3ef9576f40013c3969179b3189ee95 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 27 Feb 2018 22:06:03 +0000 Subject: [PATCH] PR translation/84207 - Hard coded plural in gimple-fold.c gcc/ChangeLog: PR translation/84207 * diagnostic-core.h (warning_n, error_n, inform_n): Change n argument to unsigned HOST_WIDE_INT. * diagnostic.c (warning_n, error_n, inform_n): Ditto. (diagnostic_n_impl): Ditto. Handle arguments in excess of LONG_MAX. * gimple-ssa-sprintf.c (format_directive): Simplify inform_n call. * tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Use warning_n. From-SVN: r258044 --- gcc/ChangeLog | 10 +++++++++ gcc/diagnostic-core.h | 13 +++++++----- gcc/diagnostic.c | 35 ++++++++++++++++++------------ gcc/gimple-ssa-sprintf.c | 5 +---- gcc/tree-ssa-strlen.c | 46 ++++++++++++++++++++-------------------- 5 files changed, 64 insertions(+), 45 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d56af0f7363..292bf8559a6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2018-02-27 Martin Sebor + + PR translation/84207 + * diagnostic-core.h (warning_n, error_n, inform_n): Change + n argument to unsigned HOST_WIDE_INT. + * diagnostic.c (warning_n, error_n, inform_n): Ditto. + (diagnostic_n_impl): Ditto. Handle arguments in excess of LONG_MAX. + * gimple-ssa-sprintf.c (format_directive): Simplify inform_n call. + * tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Use warning_n. + 2018-02-27 Richard Biener PR tree-optimization/84512 diff --git a/gcc/diagnostic-core.h b/gcc/diagnostic-core.h index 37cb7e367e9..aa5807e17e0 100644 --- a/gcc/diagnostic-core.h +++ b/gcc/diagnostic-core.h @@ -59,17 +59,19 @@ extern void internal_error_no_backtrace (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2) ATTRIBUTE_NORETURN; /* Pass one of the OPT_W* from options.h as the first parameter. */ extern bool warning (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); -extern bool warning_n (location_t, int, int, const char *, const char *, ...) +extern bool warning_n (location_t, int, unsigned HOST_WIDE_INT, + const char *, const char *, ...) ATTRIBUTE_GCC_DIAG(4,6) ATTRIBUTE_GCC_DIAG(5,6); -extern bool warning_n (rich_location *, int, int, const char *, - const char *, ...) +extern bool warning_n (rich_location *, int, unsigned HOST_WIDE_INT, + const char *, const char *, ...) ATTRIBUTE_GCC_DIAG(4, 6) ATTRIBUTE_GCC_DIAG(5, 6); extern bool warning_at (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); extern bool warning_at (rich_location *, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2); -extern void error_n (location_t, int, const char *, const char *, ...) +extern void error_n (location_t, unsigned HOST_WIDE_INT, const char *, + const char *, ...) ATTRIBUTE_GCC_DIAG(3,5) ATTRIBUTE_GCC_DIAG(4,5); extern void error_at (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); extern void error_at (rich_location *, const char *, ...) @@ -87,7 +89,8 @@ extern bool permerror (rich_location *, const char *, extern void sorry (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2); extern void inform (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); extern void inform (rich_location *, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); -extern void inform_n (location_t, int, const char *, const char *, ...) +extern void inform_n (location_t, unsigned HOST_WIDE_INT, const char *, + const char *, ...) ATTRIBUTE_GCC_DIAG(3,5) ATTRIBUTE_GCC_DIAG(4,5); extern void verbatim (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2); extern bool emit_diagnostic (diagnostic_t, location_t, int, diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c index acc44b18113..e22c17bc02c 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -51,8 +51,8 @@ along with GCC; see the file COPYING3. If not see /* Prototypes. */ static bool diagnostic_impl (rich_location *, int, const char *, va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(3,0); -static bool diagnostic_n_impl (rich_location *, int, int, const char *, - const char *, va_list *, +static bool diagnostic_n_impl (rich_location *, int, unsigned HOST_WIDE_INT, + const char *, const char *, va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(5,0); static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN; @@ -1111,15 +1111,24 @@ diagnostic_impl (rich_location *richloc, int opt, /* Implement inform_n, warning_n, and error_n, as documented and defined below. */ static bool -diagnostic_n_impl (rich_location *richloc, int opt, int n, +diagnostic_n_impl (rich_location *richloc, int opt, unsigned HOST_WIDE_INT n, const char *singular_gmsgid, const char *plural_gmsgid, va_list *ap, diagnostic_t kind) { diagnostic_info diagnostic; - diagnostic_set_info_translated (&diagnostic, - ngettext (singular_gmsgid, plural_gmsgid, n), - ap, richloc, kind); + unsigned long gtn; + + if (sizeof n <= sizeof gtn) + gtn = n; + else + /* Use the largest number ngettext can handle, otherwise + preserve the six least significant decimal digits for + languages where the plural form depends on them. */ + gtn = n <= ULONG_MAX ? n : n % 1000000LU + 1000000LU; + + const char *text = ngettext (singular_gmsgid, plural_gmsgid, gtn); + diagnostic_set_info_translated (&diagnostic, text, ap, richloc, kind); if (kind == DK_WARNING) diagnostic.option_index = opt; return diagnostic_report_diagnostic (global_dc, &diagnostic); @@ -1176,8 +1185,8 @@ inform (rich_location *richloc, const char *gmsgid, ...) /* An informative note at LOCATION. Use this for additional details on an error message. */ void -inform_n (location_t location, int n, const char *singular_gmsgid, - const char *plural_gmsgid, ...) +inform_n (location_t location, unsigned HOST_WIDE_INT n, + const char *singular_gmsgid, const char *plural_gmsgid, ...) { va_list ap; va_start (ap, plural_gmsgid); @@ -1233,7 +1242,7 @@ warning_at (rich_location *richloc, int opt, const char *gmsgid, ...) /* Same as warning_n plural variant below, but using RICHLOC. */ bool -warning_n (rich_location *richloc, int opt, int n, +warning_n (rich_location *richloc, int opt, unsigned HOST_WIDE_INT n, const char *singular_gmsgid, const char *plural_gmsgid, ...) { gcc_assert (richloc); @@ -1252,8 +1261,8 @@ warning_n (rich_location *richloc, int opt, int n, Returns true if the warning was printed, false if it was inhibited. */ bool -warning_n (location_t location, int opt, int n, const char *singular_gmsgid, - const char *plural_gmsgid, ...) +warning_n (location_t location, int opt, unsigned HOST_WIDE_INT n, + const char *singular_gmsgid, const char *plural_gmsgid, ...) { va_list ap; va_start (ap, plural_gmsgid); @@ -1350,8 +1359,8 @@ error (const char *gmsgid, ...) /* A hard error: the code is definitely ill-formed, and an object file will not be produced. */ void -error_n (location_t location, int n, const char *singular_gmsgid, - const char *plural_gmsgid, ...) +error_n (location_t location, unsigned HOST_WIDE_INT n, + const char *singular_gmsgid, const char *plural_gmsgid, ...) { va_list ap; va_start (ap, plural_gmsgid); diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index 1189d9fea35..83d71f0d644 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -2952,10 +2952,7 @@ format_directive (const sprintf_dom_walker::call_info &info, && fmtres.range.likely < fmtres.range.max) /* Some languages have special plural rules even for large values, but it is periodic with period of 10, 100, 1000 etc. */ - inform_n (info.fmtloc, - fmtres.range.likely > INT_MAX - ? (fmtres.range.likely % 1000000) + 1000000 - : fmtres.range.likely, + inform_n (info.fmtloc, fmtres.range.likely, "assuming directive output of %wu byte", "assuming directive output of %wu bytes", fmtres.range.likely); diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 71ed0ff1b45..1266f399373 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -1943,27 +1943,27 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt) gcall *call = as_a (stmt); if (lenrange[0] == cntrange[1] && cntrange[0] == cntrange[1]) - return warning_at (callloc, OPT_Wstringop_truncation, - (integer_onep (cnt) - ? G_("%G%qD output truncated before terminating " - "nul copying %E byte from a string of the " - "same length") - : G_("%G%qD output truncated before terminating nul " - "copying %E bytes from a string of the same " - "length")), - call, func, cnt); + return warning_n (callloc, OPT_Wstringop_truncation, + cntrange[0].to_uhwi (), + "%G%qD output truncated before terminating " + "nul copying %E byte from a string of the " + "same length", + "%G%qD output truncated before terminating nul " + "copying %E bytes from a string of the same " + "length", + call, func, cnt); else if (wi::geu_p (lenrange[0], cntrange[1])) { /* The shortest string is longer than the upper bound of the count so the truncation is certain. */ if (cntrange[0] == cntrange[1]) - return warning_at (callloc, OPT_Wstringop_truncation, - integer_onep (cnt) - ? G_("%G%qD output truncated copying %E byte " - "from a string of length %wu") - : G_("%G%qD output truncated copying %E bytes " - "from a string of length %wu"), - call, func, cnt, lenrange[0].to_uhwi ()); + return warning_n (callloc, OPT_Wstringop_truncation, + cntrange[0].to_uhwi (), + "%G%qD output truncated copying %E byte " + "from a string of length %wu", + "%G%qD output truncated copying %E bytes " + "from a string of length %wu", + call, func, cnt, lenrange[0].to_uhwi ()); return warning_at (callloc, OPT_Wstringop_truncation, "%G%qD output truncated copying between %wu " @@ -1976,13 +1976,13 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt) /* The longest string is longer than the upper bound of the count so the truncation is possible. */ if (cntrange[0] == cntrange[1]) - return warning_at (callloc, OPT_Wstringop_truncation, - integer_onep (cnt) - ? G_("%G%qD output may be truncated copying %E " - "byte from a string of length %wu") - : G_("%G%qD output may be truncated copying %E " - "bytes from a string of length %wu"), - call, func, cnt, lenrange[1].to_uhwi ()); + return warning_n (callloc, OPT_Wstringop_truncation, + cntrange[0].to_uhwi (), + "%G%qD output may be truncated copying %E " + "byte from a string of length %wu", + "%G%qD output may be truncated copying %E " + "bytes from a string of length %wu", + call, func, cnt, lenrange[1].to_uhwi ()); return warning_at (callloc, OPT_Wstringop_truncation, "%G%qD output may be truncated copying between %wu " -- 2.30.2