Commit 1c89478a by Martin Sebor Committed by Martin Sebor

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
parent 76bd270a
2018-02-27 Martin Sebor <msebor@redhat.com>
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 <rguenther@suse.de> 2018-02-27 Richard Biener <rguenther@suse.de>
PR tree-optimization/84512 PR tree-optimization/84512
......
...@@ -59,17 +59,19 @@ extern void internal_error_no_backtrace (const char *, ...) ...@@ -59,17 +59,19 @@ extern void internal_error_no_backtrace (const char *, ...)
ATTRIBUTE_GCC_DIAG(1,2) ATTRIBUTE_NORETURN; ATTRIBUTE_GCC_DIAG(1,2) ATTRIBUTE_NORETURN;
/* Pass one of the OPT_W* from options.h as the first parameter. */ /* 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 (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); ATTRIBUTE_GCC_DIAG(4,6) ATTRIBUTE_GCC_DIAG(5,6);
extern bool warning_n (rich_location *, int, int, const char *, extern bool warning_n (rich_location *, int, unsigned HOST_WIDE_INT,
const char *, ...) const char *, const char *, ...)
ATTRIBUTE_GCC_DIAG(4, 6) ATTRIBUTE_GCC_DIAG(5, 6); ATTRIBUTE_GCC_DIAG(4, 6) ATTRIBUTE_GCC_DIAG(5, 6);
extern bool warning_at (location_t, int, const char *, ...) extern bool warning_at (location_t, int, const char *, ...)
ATTRIBUTE_GCC_DIAG(3,4); ATTRIBUTE_GCC_DIAG(3,4);
extern bool warning_at (rich_location *, int, const char *, ...) extern bool warning_at (rich_location *, int, const char *, ...)
ATTRIBUTE_GCC_DIAG(3,4); ATTRIBUTE_GCC_DIAG(3,4);
extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2); 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); 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 (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
extern void error_at (rich_location *, const char *, ...) extern void error_at (rich_location *, const char *, ...)
...@@ -87,7 +89,8 @@ extern bool permerror (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 sorry (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
extern void inform (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); 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 (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); ATTRIBUTE_GCC_DIAG(3,5) ATTRIBUTE_GCC_DIAG(4,5);
extern void verbatim (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2); extern void verbatim (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
extern bool emit_diagnostic (diagnostic_t, location_t, int, extern bool emit_diagnostic (diagnostic_t, location_t, int,
......
...@@ -51,8 +51,8 @@ along with GCC; see the file COPYING3. If not see ...@@ -51,8 +51,8 @@ along with GCC; see the file COPYING3. If not see
/* Prototypes. */ /* Prototypes. */
static bool diagnostic_impl (rich_location *, int, const char *, static bool diagnostic_impl (rich_location *, int, const char *,
va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(3,0); va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(3,0);
static bool diagnostic_n_impl (rich_location *, int, int, const char *, static bool diagnostic_n_impl (rich_location *, int, unsigned HOST_WIDE_INT,
const char *, va_list *, const char *, const char *, va_list *,
diagnostic_t) ATTRIBUTE_GCC_DIAG(5,0); diagnostic_t) ATTRIBUTE_GCC_DIAG(5,0);
static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN; static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN;
...@@ -1111,15 +1111,24 @@ diagnostic_impl (rich_location *richloc, int opt, ...@@ -1111,15 +1111,24 @@ diagnostic_impl (rich_location *richloc, int opt,
/* Implement inform_n, warning_n, and error_n, as documented and /* Implement inform_n, warning_n, and error_n, as documented and
defined below. */ defined below. */
static bool 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 *singular_gmsgid,
const char *plural_gmsgid, const char *plural_gmsgid,
va_list *ap, diagnostic_t kind) va_list *ap, diagnostic_t kind)
{ {
diagnostic_info diagnostic; diagnostic_info diagnostic;
diagnostic_set_info_translated (&diagnostic, unsigned long gtn;
ngettext (singular_gmsgid, plural_gmsgid, n),
ap, richloc, kind); 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) if (kind == DK_WARNING)
diagnostic.option_index = opt; diagnostic.option_index = opt;
return diagnostic_report_diagnostic (global_dc, &diagnostic); return diagnostic_report_diagnostic (global_dc, &diagnostic);
...@@ -1176,8 +1185,8 @@ inform (rich_location *richloc, const char *gmsgid, ...) ...@@ -1176,8 +1185,8 @@ inform (rich_location *richloc, const char *gmsgid, ...)
/* An informative note at LOCATION. Use this for additional details on an /* An informative note at LOCATION. Use this for additional details on an
error message. */ error message. */
void void
inform_n (location_t location, int n, const char *singular_gmsgid, inform_n (location_t location, unsigned HOST_WIDE_INT n,
const char *plural_gmsgid, ...) const char *singular_gmsgid, const char *plural_gmsgid, ...)
{ {
va_list ap; va_list ap;
va_start (ap, plural_gmsgid); va_start (ap, plural_gmsgid);
...@@ -1233,7 +1242,7 @@ warning_at (rich_location *richloc, int opt, const char *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. */ /* Same as warning_n plural variant below, but using RICHLOC. */
bool 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, ...) const char *singular_gmsgid, const char *plural_gmsgid, ...)
{ {
gcc_assert (richloc); gcc_assert (richloc);
...@@ -1252,8 +1261,8 @@ warning_n (rich_location *richloc, int opt, int n, ...@@ -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. */ Returns true if the warning was printed, false if it was inhibited. */
bool bool
warning_n (location_t location, int opt, int n, const char *singular_gmsgid, warning_n (location_t location, int opt, unsigned HOST_WIDE_INT n,
const char *plural_gmsgid, ...) const char *singular_gmsgid, const char *plural_gmsgid, ...)
{ {
va_list ap; va_list ap;
va_start (ap, plural_gmsgid); va_start (ap, plural_gmsgid);
...@@ -1350,8 +1359,8 @@ error (const char *gmsgid, ...) ...@@ -1350,8 +1359,8 @@ error (const char *gmsgid, ...)
/* A hard error: the code is definitely ill-formed, and an object file /* A hard error: the code is definitely ill-formed, and an object file
will not be produced. */ will not be produced. */
void void
error_n (location_t location, int n, const char *singular_gmsgid, error_n (location_t location, unsigned HOST_WIDE_INT n,
const char *plural_gmsgid, ...) const char *singular_gmsgid, const char *plural_gmsgid, ...)
{ {
va_list ap; va_list ap;
va_start (ap, plural_gmsgid); va_start (ap, plural_gmsgid);
......
...@@ -2952,10 +2952,7 @@ format_directive (const sprintf_dom_walker::call_info &info, ...@@ -2952,10 +2952,7 @@ format_directive (const sprintf_dom_walker::call_info &info,
&& fmtres.range.likely < fmtres.range.max) && fmtres.range.likely < fmtres.range.max)
/* Some languages have special plural rules even for large values, /* Some languages have special plural rules even for large values,
but it is periodic with period of 10, 100, 1000 etc. */ but it is periodic with period of 10, 100, 1000 etc. */
inform_n (info.fmtloc, inform_n (info.fmtloc, fmtres.range.likely,
fmtres.range.likely > INT_MAX
? (fmtres.range.likely % 1000000) + 1000000
: fmtres.range.likely,
"assuming directive output of %wu byte", "assuming directive output of %wu byte",
"assuming directive output of %wu bytes", "assuming directive output of %wu bytes",
fmtres.range.likely); fmtres.range.likely);
......
...@@ -1943,27 +1943,27 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt) ...@@ -1943,27 +1943,27 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt)
gcall *call = as_a <gcall *> (stmt); gcall *call = as_a <gcall *> (stmt);
if (lenrange[0] == cntrange[1] && cntrange[0] == cntrange[1]) if (lenrange[0] == cntrange[1] && cntrange[0] == cntrange[1])
return warning_at (callloc, OPT_Wstringop_truncation, return warning_n (callloc, OPT_Wstringop_truncation,
(integer_onep (cnt) cntrange[0].to_uhwi (),
? G_("%G%qD output truncated before terminating " "%G%qD output truncated before terminating "
"nul copying %E byte from a string of the " "nul copying %E byte from a string of the "
"same length") "same length",
: G_("%G%qD output truncated before terminating nul " "%G%qD output truncated before terminating nul "
"copying %E bytes from a string of the same " "copying %E bytes from a string of the same "
"length")), "length",
call, func, cnt); call, func, cnt);
else if (wi::geu_p (lenrange[0], cntrange[1])) else if (wi::geu_p (lenrange[0], cntrange[1]))
{ {
/* The shortest string is longer than the upper bound of /* The shortest string is longer than the upper bound of
the count so the truncation is certain. */ the count so the truncation is certain. */
if (cntrange[0] == cntrange[1]) if (cntrange[0] == cntrange[1])
return warning_at (callloc, OPT_Wstringop_truncation, return warning_n (callloc, OPT_Wstringop_truncation,
integer_onep (cnt) cntrange[0].to_uhwi (),
? G_("%G%qD output truncated copying %E byte " "%G%qD output truncated copying %E byte "
"from a string of length %wu") "from a string of length %wu",
: G_("%G%qD output truncated copying %E bytes " "%G%qD output truncated copying %E bytes "
"from a string of length %wu"), "from a string of length %wu",
call, func, cnt, lenrange[0].to_uhwi ()); call, func, cnt, lenrange[0].to_uhwi ());
return warning_at (callloc, OPT_Wstringop_truncation, return warning_at (callloc, OPT_Wstringop_truncation,
"%G%qD output truncated copying between %wu " "%G%qD output truncated copying between %wu "
...@@ -1976,13 +1976,13 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt) ...@@ -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 longest string is longer than the upper bound of
the count so the truncation is possible. */ the count so the truncation is possible. */
if (cntrange[0] == cntrange[1]) if (cntrange[0] == cntrange[1])
return warning_at (callloc, OPT_Wstringop_truncation, return warning_n (callloc, OPT_Wstringop_truncation,
integer_onep (cnt) cntrange[0].to_uhwi (),
? G_("%G%qD output may be truncated copying %E " "%G%qD output may be truncated copying %E "
"byte from a string of length %wu") "byte from a string of length %wu",
: G_("%G%qD output may be truncated copying %E " "%G%qD output may be truncated copying %E "
"bytes from a string of length %wu"), "bytes from a string of length %wu",
call, func, cnt, lenrange[1].to_uhwi ()); call, func, cnt, lenrange[1].to_uhwi ());
return warning_at (callloc, OPT_Wstringop_truncation, return warning_at (callloc, OPT_Wstringop_truncation,
"%G%qD output may be truncated copying between %wu " "%G%qD output may be truncated copying between %wu "
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment