This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] i18n fixes in gimple-ssa-sprintf.c


Hi!

This patch fixes a couple of i18n bugs in gimple-ssa-sprintf.c.

One issue was incorrect format attribute for format_warning_at_substring,
which has ... and thus shouldn't use 0 for the last argument, but the first
non-named argument position.

Another one is that a couple of fmtwarn calls need plural form handling,
so I've introduced new substring-locations.[ch] entrypoints for that;
in order to be able to successfully extract the plural form translatable
strings from those, it can't use the const function pointer hack to shorten
the function name, nor can use the conditionals to pick the format strings.

Another thing is that the file had
#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
which has hidden a couple of issues, missing ATTRIBUTE_GCC_DIAG on the
const fn pointer and lots of missing casts to int for size_t arguments
passed as length to %.*s.

Also, if we use the const fn pointer hack to shorten the function name,
exgettext doesn't really work on it, so I had to add G_(...) around a couple
of non-conditional format strings, the conditional ones already had it.
Though for those I got rid of the fmtstr temporaries which just caused
gcc not to see the format strings and be able to diagnose issues; plus is
bad for -Wformat-security too.

Bootstrapped/regtested on x86_64-linux and i686-linux, additionally tested
with
make check-gcc RUNTESTFLAGS='--target_board=unix\{-m32,-m64\} tree-ssa.exp=builtin-sprintf*'
with unpatched and patched compiler and diffed gcc/testsuite/gcc/gcc.log in
between the two to make sure no diagnostics differences.  And also run make
gcc.pot and verified all the strings I expected to be translatable to be
there, in the desired form (plural-form vs. normal).  Ok for trunk?

2018-03-02  Jakub Jelinek  <jakub@redhat.com>

	* substring-locations.h (format_warning_va): Formatting fix for
	ATTRIBUTE_GCC_DIAG.
	(format_warning_at_substring): Fix up ATTRIBUTE_GCC_DIAG second
	argument.
	(format_warning_n_va, format_warning_at_substring_n): New prototypes.
	* substring-locations.c: Include intl.h.
	(format_warning_va): Turned into small wrapper around
	format_warning_n_va, renamed to ...
	(format_warning_n_va): ... this, add N and PLURAL_GMSGID arguments,
	rename GMSGID to SINGULAR_GMSGID, if SINGULAR_GMSGID != PLURAL_GMSGID,
	use ngettext.
	(format_warning_at_substring_n): New function.
	* gimple-ssa-sprintf.c: Remove GCC diagnostic ignored pragma.
	(fmtwarn): Add ATTRIBUTE_GCC_DIAG.
	(maybe_warn, format_directive, parse_directive): Use
	format_warning_at_substring_n where appropriate, get rid of all the
	fmtstr temporaries, move conditionals with G_() wrapped string literals
	directly into fmtwarn arguments, cast dir.len to (int), wrap
	direct string literal arguments of fmtwarn with G_(), formatting fixes.

--- gcc/substring-locations.h.jj	2018-01-03 10:19:53.824533733 +0100
+++ gcc/substring-locations.h	2018-03-01 20:58:57.500660725 +0100
@@ -80,13 +80,29 @@ extern bool format_warning_va (const sub
 			       location_t param_loc,
 			       const char *corrected_substring,
 			       int opt, const char *gmsgid, va_list *ap)
-  ATTRIBUTE_GCC_DIAG (5,0);
+  ATTRIBUTE_GCC_DIAG (5, 0);
+
+extern bool format_warning_n_va (const substring_loc &fmt_loc,
+				 location_t param_loc,
+				 const char *corrected_substring,
+				 int opt, unsigned HOST_WIDE_INT n,
+				 const char *singular_gmsgid,
+				 const char *plural_gmsgid, va_list *ap)
+  ATTRIBUTE_GCC_DIAG (6, 0) ATTRIBUTE_GCC_DIAG (7, 0);
 
 extern bool format_warning_at_substring (const substring_loc &fmt_loc,
 					 location_t param_loc,
 					 const char *corrected_substring,
 					 int opt, const char *gmsgid, ...)
-  ATTRIBUTE_GCC_DIAG (5,0);
+  ATTRIBUTE_GCC_DIAG (5, 6);
+
+extern bool format_warning_at_substring_n (const substring_loc &fmt_loc,
+					   location_t param_loc,
+					   const char *corrected_substring,
+					   int opt, unsigned HOST_WIDE_INT n,
+					   const char *singular_gmsgid,
+					   const char *plural_gmsgid, ...)
+  ATTRIBUTE_GCC_DIAG (6, 8) ATTRIBUTE_GCC_DIAG (7, 8);
 
 /* Implementation detail, for use when implementing
    LANG_HOOKS_GET_SUBSTRING_LOCATION.  */
--- gcc/substring-locations.c.jj	2018-01-03 10:19:55.240533971 +0100
+++ gcc/substring-locations.c	2018-03-01 19:46:46.887222408 +0100
@@ -20,14 +20,17 @@ along with GCC; see the file COPYING3.
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "intl.h"
 #include "diagnostic.h"
 #include "cpplib.h"
 #include "tree.h"
 #include "langhooks.h"
 #include "substring-locations.h"
 
-/* Emit a warning governed by option OPT, using GMSGID as the format
-   string and AP as its arguments.
+/* Emit a warning governed by option OPT, using SINGULAR_GMSGID as the
+   format string (or if PLURAL_GMSGID is different from SINGULAR_GMSGID,
+   using SINGULAR_GMSGID, PLURAL_GMSGID and N as arguments to ngettext)
+   and AP as its arguments.
 
    Attempt to obtain precise location information within a string
    literal from FMT_LOC.
@@ -97,12 +100,13 @@ along with GCC; see the file COPYING3.
 
    Return true if a warning was emitted, false otherwise.  */
 
-ATTRIBUTE_GCC_DIAG (5,0)
 bool
-format_warning_va (const substring_loc &fmt_loc,
-		   location_t param_loc,
-		   const char *corrected_substring,
-		   int opt, const char *gmsgid, va_list *ap)
+format_warning_n_va (const substring_loc &fmt_loc,
+		     location_t param_loc,
+		     const char *corrected_substring,
+		     int opt, unsigned HOST_WIDE_INT n,
+		     const char *singular_gmsgid,
+		     const char *plural_gmsgid, va_list *ap)
 {
   bool substring_within_range = false;
   location_t primary_loc;
@@ -143,7 +147,25 @@ format_warning_va (const substring_loc &
     richloc.add_fixit_replace (fmt_substring_range, corrected_substring);
 
   diagnostic_info diagnostic;
-  diagnostic_set_info (&diagnostic, gmsgid, ap, &richloc, DK_WARNING);
+  if (singular_gmsgid != plural_gmsgid)
+    {
+      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,
+				      DK_WARNING);
+    }
+  else
+    diagnostic_set_info (&diagnostic, singular_gmsgid, ap, &richloc,
+			 DK_WARNING);
   diagnostic.option_index = opt;
   bool warned = diagnostic_report_diagnostic (global_dc, &diagnostic);
 
@@ -162,6 +184,18 @@ format_warning_va (const substring_loc &
   return warned;
 }
 
+/* Singular-only version of the above.  */
+
+bool
+format_warning_va (const substring_loc &fmt_loc,
+		   location_t param_loc,
+		   const char *corrected_substring,
+		   int opt, const char *gmsgid, va_list *ap)
+{
+  return format_warning_n_va (fmt_loc, param_loc, corrected_substring, opt,
+			      0, gmsgid, gmsgid, ap);
+}
+
 /* Variadic call to format_warning_va.  */
 
 bool
@@ -177,6 +211,26 @@ format_warning_at_substring (const subst
   va_end (ap);
 
   return warned;
+}
+
+/* Variadic call to format_warning_n_va.  */
+
+bool
+format_warning_at_substring_n (const substring_loc &fmt_loc,
+			       location_t param_loc,
+			       const char *corrected_substring,
+			       int opt, unsigned HOST_WIDE_INT n,
+			       const char *singular_gmsgid,
+			       const char *plural_gmsgid, ...)
+{
+  va_list ap;
+  va_start (ap, plural_gmsgid);
+  bool warned = format_warning_n_va (fmt_loc, param_loc, corrected_substring,
+				     opt, n, singular_gmsgid, plural_gmsgid,
+				     &ap);
+  va_end (ap);
+
+  return warned;
 }
 
 /* Attempt to determine the source location of the substring.
--- gcc/gimple-ssa-sprintf.c.jj	2018-02-27 23:16:19.747948912 +0100
+++ gcc/gimple-ssa-sprintf.c	2018-03-01 21:26:37.728861287 +0100
@@ -592,14 +592,12 @@ get_format_string (tree format, location
 /* The format_warning_at_substring function is not used here in a way
    that makes using attribute format viable.  Suppress the warning.  */
 
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
-
 /* For convenience and brevity.  */
 
 static bool
   (* const fmtwarn) (const substring_loc &, location_t,
 		     const char *, int, const char *, ...)
+  ATTRIBUTE_GCC_DIAG (5, 6)
   = format_warning_at_substring;
 
 /* Format length modifiers.  */
@@ -2489,113 +2487,119 @@ maybe_warn (substring_loc &dirloc, locat
 	  /* This is the terminating nul.  */
 	  gcc_assert (res.min == 1 && res.min == res.max);
 
-	  const char *fmtstr
-	    = (info.bounded
-	       ? (maybe
-		  ? G_("%qE output may be truncated before the last format "
-		       "character")
-		  : G_("%qE output truncated before the last format character"))
-	       : (maybe
-		  ? G_("%qE may write a terminating nul past the end "
-		       "of the destination")
-		  : G_("%qE writing a terminating nul past the end "
-		       "of the destination")));
-
 	  return fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
-			  fmtstr, info.func);
+			  info.bounded
+			  ? (maybe
+			     ? G_("%qE output may be truncated before the "
+				  "last format character")
+			     : G_("%qE output truncated before the last "
+				  "format character"))
+			  : (maybe
+			     ? G_("%qE may write a terminating nul past the "
+				  "end of the destination")
+			     : G_("%qE writing a terminating nul past the "
+				  "end of the destination")),
+			  info.func);
 	}
 
       if (res.min == res.max)
 	{
-	  const char* fmtstr
-	    = (res.min == 1
-	       ? (info.bounded
-		  ? (maybe
-		     ? G_("%<%.*s%> directive output may be truncated writing "
-			  "%wu byte into a region of size %wu")
-		     : G_("%<%.*s%> directive output truncated writing "
-			  "%wu byte into a region of size %wu"))
-		  : G_("%<%.*s%> directive writing %wu byte "
-		       "into a region of size %wu"))
-	       : (info.bounded
-		  ? (maybe
-		     ? G_("%<%.*s%> directive output may be truncated writing "
-			  "%wu bytes into a region of size %wu")
-		     : G_("%<%.*s%> directive output truncated writing "
-			  "%wu bytes into a region of size %wu"))
-		  : G_("%<%.*s%> directive writing %wu bytes "
-		       "into a region of size %wu")));
-	  return fmtwarn (dirloc, argloc, NULL,
-			  info.warnopt (), fmtstr, dir.len,
-			  target_to_host (hostdir, sizeof hostdir, dir.beg),
-			  res.min, navail);
+	  const char *d = target_to_host (hostdir, sizeof hostdir, dir.beg);
+	  if (!info.bounded)
+	    return format_warning_at_substring_n (dirloc, argloc, NULL,
+						  info.warnopt (), res.min,
+						  "%<%.*s%> directive writing "
+						  "%wu byte into a region of "
+						  "size %wu",
+						  "%<%.*s%> directive writing "
+						  "%wu bytes into a region of "
+						  "size %wu",
+						  (int) dir.len, d, res.min,
+						  navail);
+	  else if (maybe)
+	    return format_warning_at_substring_n (dirloc, argloc, NULL,
+						  info.warnopt (), res.min,
+						  "%<%.*s%> directive output "
+						  "may be truncated writing "
+						  "%wu byte into a region of "
+						  "size %wu",
+						  "%<%.*s%> directive output "
+						  "may be truncated writing "
+						  "%wu bytes into a region of "
+						  "size %wu",
+						  (int) dir.len, d, res.min,
+						  navail);
+	  else
+	    return format_warning_at_substring_n (dirloc, argloc, NULL,
+						  info.warnopt (), res.min,
+						  "%<%.*s%> directive output "
+						  "truncated writing %wu byte "
+						  "into a region of size %wu",
+						  "%<%.*s%> directive output "
+						  "truncated writing %wu bytes"
+						  " into a region of size %wu",
+						  (int) dir.len, d, res.min,
+						  navail);
 	}
-
       if (res.min == 0 && res.max < maxbytes)
-	{
-	  const char* fmtstr
-	    = (info.bounded
-	       ? (maybe
-		  ? G_("%<%.*s%> directive output may be truncated writing "
-		       "up to %wu bytes into a region of size %wu")
-		  : G_("%<%.*s%> directive output truncated writing "
-		       "up to %wu bytes into a region of size %wu"))
-	       : G_("%<%.*s%> directive writing up to %wu bytes "
-		    "into a region of size %wu"));
-	  return fmtwarn (dirloc, argloc, NULL,
-			  info.warnopt (), fmtstr, dir.len,
-			  target_to_host (hostdir, sizeof hostdir, dir.beg),
-			  res.max, navail);
-	}
+	return fmtwarn (dirloc, argloc, NULL,
+			info.warnopt (),
+			info.bounded
+			? (maybe
+			   ? G_("%<%.*s%> directive output may be truncated "
+				"writing up to %wu bytes into a region of "
+				"size %wu")
+			   : G_("%<%.*s%> directive output truncated writing "
+				"up to %wu bytes into a region of size %wu"))
+			: G_("%<%.*s%> directive writing up to %wu bytes "
+			     "into a region of size %wu"), (int) dir.len,
+			target_to_host (hostdir, sizeof hostdir, dir.beg),
+			res.max, navail);
 
       if (res.min == 0 && maxbytes <= res.max)
-	{
-	  /* This is a special case to avoid issuing the potentially
-	     confusing warning:
-	       writing 0 or more bytes into a region of size 0.  */
-	  const char* fmtstr
-	    = (info.bounded
-	       ? (maybe
-		  ? G_("%<%.*s%> directive output may be truncated writing "
-		       "likely %wu or more bytes into a region of size %wu")
-		  : G_("%<%.*s%> directive output truncated writing "
-		       "likely %wu or more bytes into a region of size %wu"))
-	       : G_("%<%.*s%> directive writing likely %wu or more bytes "
-		    "into a region of size %wu"));
-	  return fmtwarn (dirloc, argloc, NULL,
-			  info.warnopt (), fmtstr, dir.len,
-			  target_to_host (hostdir, sizeof hostdir, dir.beg),
-			  res.likely, navail);
-	}
+	/* This is a special case to avoid issuing the potentially
+	   confusing warning:
+	     writing 0 or more bytes into a region of size 0.  */
+	return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
+			info.bounded
+			? (maybe
+			   ? G_("%<%.*s%> directive output may be truncated "
+				"writing likely %wu or more bytes into a "
+				"region of size %wu")
+			   : G_("%<%.*s%> directive output truncated writing "
+				"likely %wu or more bytes into a region of "
+				"size %wu"))
+			: G_("%<%.*s%> directive writing likely %wu or more "
+			     "bytes into a region of size %wu"), (int) dir.len,
+			target_to_host (hostdir, sizeof hostdir, dir.beg),
+			res.likely, navail);
 
       if (res.max < maxbytes)
-	{
-	  const char* fmtstr
-	    = (info.bounded
-	       ? (maybe
-		  ? G_("%<%.*s%> directive output may be truncated writing "
-		       "between %wu and %wu bytes into a region of size %wu")
-		  : G_("%<%.*s%> directive output truncated writing "
-		       "between %wu and %wu bytes into a region of size %wu"))
-	       : G_("%<%.*s%> directive writing between %wu and "
-		    "%wu bytes into a region of size %wu"));
-	  return fmtwarn (dirloc, argloc, NULL,
-			  info.warnopt (), fmtstr, dir.len,
-			  target_to_host (hostdir, sizeof hostdir, dir.beg),
-			  res.min, res.max, navail);
-	}
-
-      const char* fmtstr
-	= (info.bounded
-	   ? (maybe
-	      ? G_("%<%.*s%> directive output may be truncated writing "
-		   "%wu or more bytes into a region of size %wu")
-	      : G_("%<%.*s%> directive output truncated writing "
-		   "%wu or more bytes into a region of size %wu"))
-	   : G_("%<%.*s%> directive writing %wu or more bytes "
-		"into a region of size %wu"));
-      return fmtwarn (dirloc, argloc, NULL,
-		      info.warnopt (), fmtstr, dir.len,
+	return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
+			info.bounded
+			? (maybe
+			   ? G_("%<%.*s%> directive output may be truncated "
+				"writing between %wu and %wu bytes into a "
+				"region of size %wu")
+			   : G_("%<%.*s%> directive output truncated "
+				"writing between %wu and %wu bytes into a "
+				"region of size %wu"))
+			: G_("%<%.*s%> directive writing between %wu and "
+			     "%wu bytes into a region of size %wu"),
+			(int) dir.len,
+			target_to_host (hostdir, sizeof hostdir, dir.beg),
+			res.min, res.max, navail);
+
+      return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
+		      info.bounded
+		      ? (maybe
+			 ? G_("%<%.*s%> directive output may be truncated "
+			      "writing %wu or more bytes into a region of "
+			      "size %wu")
+			 : G_("%<%.*s%> directive output truncated writing "
+			      "%wu or more bytes into a region of size %wu"))
+		      : G_("%<%.*s%> directive writing %wu or more bytes "
+			   "into a region of size %wu"), (int) dir.len,
 		      target_to_host (hostdir, sizeof hostdir, dir.beg),
 		      res.min, navail);
     }
@@ -2617,122 +2621,128 @@ maybe_warn (substring_loc &dirloc, locat
     {
       gcc_assert (res.min == 1 && res.min == res.max);
 
-      const char *fmtstr
-	= (info.bounded
-	   ? (maybe
-	      ? G_("%qE output may be truncated before the last format "
-		   "character")
-	      : G_("%qE output truncated before the last format character"))
-	   : (maybe
-	      ? G_("%qE may write a terminating nul past the end "
-		   "of the destination")
-	      : G_("%qE writing a terminating nul past the end "
-		   "of the destination")));
-
-      return fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (), fmtstr,
-		      info.func);
+      return fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
+		      info.bounded
+		      ? (maybe
+			 ? G_("%qE output may be truncated before the last "
+			      "format character")
+			 : G_("%qE output truncated before the last format "
+			      "character"))
+		      : (maybe
+			 ? G_("%qE may write a terminating nul past the end "
+			      "of the destination")
+			 : G_("%qE writing a terminating nul past the end "
+			      "of the destination")), info.func);
     }
 
   if (res.min == res.max)
     {
-      const char* fmtstr
-	= (res.min == 1
-	   ? (info.bounded
-	      ? (maybe
-		 ? G_("%<%.*s%> directive output may be truncated writing "
-		      "%wu byte into a region of size between %wu and %wu")
-		 : G_("%<%.*s%> directive output truncated writing "
-		      "%wu byte into a region of size between %wu and %wu"))
-	      : G_("%<%.*s%> directive writing %wu byte "
-		   "into a region of size between %wu and %wu"))
-	   : (info.bounded
-	      ? (maybe
-		 ? G_("%<%.*s%> directive output may be truncated writing "
-		      "%wu bytes into a region of size between %wu and %wu")
-		 : G_("%<%.*s%> directive output truncated writing "
-		      "%wu bytes into a region of size between %wu and %wu"))
-	      : G_("%<%.*s%> directive writing %wu bytes "
-		   "into a region of size between %wu and %wu")));
-
-      return fmtwarn (dirloc, argloc, NULL,
-		      info.warnopt (), fmtstr, dir.len,
-		      target_to_host (hostdir, sizeof hostdir, dir.beg),
-		      res.min, avail_range.min, avail_range.max);
+      const char *d = target_to_host (hostdir, sizeof hostdir, dir.beg);
+      if (!info.bounded)
+	return format_warning_at_substring_n (dirloc, argloc, NULL,
+					      info.warnopt (), res.min,
+					      "%<%.*s%> directive writing "
+					      "%wu byte into a region of size "
+					      "between %wu and %wu",
+					      "%<%.*s%> directive writing "
+					      "%wu bytes into a region of size"
+					      " between %wu and %wu",
+					      (int) dir.len, d, res.min,
+					      avail_range.min,
+					      avail_range.max);
+      else if (maybe)
+	return format_warning_at_substring_n (dirloc, argloc, NULL,
+					      info.warnopt (), res.min,
+					      "%<%.*s%> directive output may "
+					      "be truncated writing %wu byte "
+					      "into a region of size between "
+					      "%wu and %wu",
+					      "%<%.*s%> directive output may "
+					      "be truncated writing %wu bytes "
+					      "into a region of size between "
+					      "%wu and %wu",
+					      (int) dir.len, d, res.min,
+					      avail_range.min,
+					      avail_range.max);
+      else
+	return format_warning_at_substring_n (dirloc, argloc, NULL,
+					      info.warnopt (), res.min,
+					      "%<%.*s%> directive output "
+					      "truncated writing %wu byte "
+					      "into a region of size between "
+					      "%wu and %wu",
+					      "%<%.*s%> directive output "
+					      "truncated writing %wu bytes "
+					      "into a region of size between "
+					      "%wu and %wu",
+					      (int) dir.len, d, res.min,
+					      avail_range.min,
+					      avail_range.max);
     }
 
   if (res.min == 0 && res.max < maxbytes)
-    {
-      const char* fmtstr
-	= (info.bounded
-	   ? (maybe
-	      ? G_("%<%.*s%> directive output may be truncated writing "
-		   "up to %wu bytes into a region of size between "
-		   "%wu and %wu")
-	      : G_("%<%.*s%> directive output truncated writing "
-		   "up to %wu bytes into a region of size between "
-		   "%wu and %wu"))
-	   : G_("%<%.*s%> directive writing up to %wu bytes "
-		"into a region of size between %wu and %wu"));
-      return fmtwarn (dirloc, argloc, NULL,
-		      info.warnopt (), fmtstr, dir.len,
-		      target_to_host (hostdir, sizeof hostdir, dir.beg),
-		      res.max, avail_range.min, avail_range.max);
-    }
+    return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
+		    info.bounded
+		    ? (maybe
+		       ? G_("%<%.*s%> directive output may be truncated "
+			    "writing up to %wu bytes into a region of size "
+			    "between %wu and %wu")
+		       : G_("%<%.*s%> directive output truncated writing "
+			    "up to %wu bytes into a region of size between "
+			    "%wu and %wu"))
+		    : G_("%<%.*s%> directive writing up to %wu bytes "
+			 "into a region of size between %wu and %wu"),
+		    (int) dir.len,
+		    target_to_host (hostdir, sizeof hostdir, dir.beg),
+		    res.max, avail_range.min, avail_range.max);
 
   if (res.min == 0 && maxbytes <= res.max)
-    {
-      /* This is a special case to avoid issuing the potentially confusing
-	 warning:
-	   writing 0 or more bytes into a region of size between 0 and N.  */
-      const char* fmtstr
-	= (info.bounded
-	   ? (maybe
-	      ? G_("%<%.*s%> directive output may be truncated writing "
-		   "likely %wu or more bytes into a region of size between "
-		   "%wu and %wu")
-	      : G_("%<%.*s%> directive output truncated writing likely "
-		   "%wu or more bytes into a region of size between "
-		   "%wu and %wu"))
-	   : G_("%<%.*s%> directive writing likely %wu or more bytes "
-		"into a region of size between %wu and %wu"));
-      return fmtwarn (dirloc, argloc, NULL,
-		      info.warnopt (), fmtstr, dir.len,
-		      target_to_host (hostdir, sizeof hostdir, dir.beg),
-		      res.likely, avail_range.min, avail_range.max);
-    }
+    /* This is a special case to avoid issuing the potentially confusing
+       warning:
+	 writing 0 or more bytes into a region of size between 0 and N.  */
+    return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
+		    info.bounded
+		    ? (maybe
+		       ? G_("%<%.*s%> directive output may be truncated "
+			    "writing likely %wu or more bytes into a region "
+			    "of size between %wu and %wu")
+		       : G_("%<%.*s%> directive output truncated writing "
+			    "likely %wu or more bytes into a region of size "
+			    "between %wu and %wu"))
+		    : G_("%<%.*s%> directive writing likely %wu or more bytes "
+			 "into a region of size between %wu and %wu"),
+		    (int) dir.len,
+		    target_to_host (hostdir, sizeof hostdir, dir.beg),
+		    res.likely, avail_range.min, avail_range.max);
 
   if (res.max < maxbytes)
-    {
-      const char* fmtstr
-	= (info.bounded
-	   ? (maybe
-	      ? G_("%<%.*s%> directive output may be truncated writing "
-		   "between %wu and %wu bytes into a region of size "
-		   "between %wu and %wu")
-	      : G_("%<%.*s%> directive output truncated writing "
-		   "between %wu and %wu bytes into a region of size "
-		   "between %wu and %wu"))
-	   : G_("%<%.*s%> directive writing between %wu and "
-		"%wu bytes into a region of size between %wu and %wu"));
-      return fmtwarn (dirloc, argloc, NULL,
-		      info.warnopt (), fmtstr, dir.len,
-		      target_to_host (hostdir, sizeof hostdir, dir.beg),
-		      res.min, res.max, avail_range.min, avail_range.max);
-    }
+    return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
+		    info.bounded
+		    ? (maybe
+		       ? G_("%<%.*s%> directive output may be truncated "
+			    "writing between %wu and %wu bytes into a region "
+			    "of size between %wu and %wu")
+		       : G_("%<%.*s%> directive output truncated writing "
+			    "between %wu and %wu bytes into a region of size "
+			    "between %wu and %wu"))
+		    : G_("%<%.*s%> directive writing between %wu and "
+			 "%wu bytes into a region of size between %wu and "
+			 "%wu"), (int) dir.len,
+		    target_to_host (hostdir, sizeof hostdir, dir.beg),
+		    res.min, res.max, avail_range.min, avail_range.max);
 
-  const char* fmtstr
-    = (info.bounded
-       ? (maybe
-	  ? G_("%<%.*s%> directive output may be truncated writing "
-	       "%wu or more bytes into a region of size between "
-	       "%wu and %wu")
-	  : G_("%<%.*s%> directive output truncated writing "
-	       "%wu or more bytes into a region of size between "
-	       "%wu and %wu"))
-       : G_("%<%.*s%> directive writing %wu or more bytes "
-	    "into a region of size between %wu and %wu"));
-  return fmtwarn (dirloc, argloc, NULL,
-		  info.warnopt (), fmtstr, dir.len,
+  return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
+		  info.bounded
+		  ? (maybe
+		     ? G_("%<%.*s%> directive output may be truncated writing "
+			  "%wu or more bytes into a region of size between "
+			  "%wu and %wu")
+		     : G_("%<%.*s%> directive output truncated writing "
+			  "%wu or more bytes into a region of size between "
+			  "%wu and %wu"))
+		  : G_("%<%.*s%> directive writing %wu or more bytes "
+		       "into a region of size between %wu and %wu"),
+		  (int) dir.len,
 		  target_to_host (hostdir, sizeof hostdir, dir.beg),
 		  res.min, avail_range.min, avail_range.max);
 }
@@ -2819,7 +2829,7 @@ format_directive (const sprintf_dom_walk
   if (fmtres.nullp)
     {
       fmtwarn (dirloc, argloc, NULL, info.warnopt (),
-	       "%<%.*s%> directive argument is null",
+	       G_("%<%.*s%> directive argument is null"),
 	       dirlen, target_to_host (hostdir, sizeof hostdir, dir.beg));
 
       /* Don't bother processing the rest of the format string.  */
@@ -2883,27 +2893,22 @@ format_directive (const sprintf_dom_walk
 	 (like Glibc does under some conditions).  */
 
       if (fmtres.range.min == fmtres.range.max)
-	warned = fmtwarn (dirloc, argloc, NULL,
-			  info.warnopt (),
-			  "%<%.*s%> directive output of %wu bytes exceeds "
-			  "minimum required size of 4095",
-			  dirlen,
+	warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
+			  G_("%<%.*s%> directive output of %wu bytes exceeds "
+			     "minimum required size of 4095"), dirlen,
 			  target_to_host (hostdir, sizeof hostdir, dir.beg),
 			  fmtres.range.min);
       else
-	{
-	  const char *fmtstr
-	    = (minunder4k
-	       ? G_("%<%.*s%> directive output between %wu and %wu "
-		    "bytes may exceed minimum required size of 4095")
-	       : G_("%<%.*s%> directive output between %wu and %wu "
-		    "bytes exceeds minimum required size of 4095"));
-
-	  warned = fmtwarn (dirloc, argloc, NULL,
-			    info.warnopt (), fmtstr, dirlen,
-			    target_to_host (hostdir, sizeof hostdir, dir.beg),
-			    fmtres.range.min, fmtres.range.max);
-	}
+	warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
+			  minunder4k
+			  ? G_("%<%.*s%> directive output between %wu and %wu "
+			       "bytes may exceed minimum required size of "
+			       "4095")
+			  : G_("%<%.*s%> directive output between %wu and %wu "
+			       "bytes exceeds minimum required size of 4095"),
+			  dirlen,
+			  target_to_host (hostdir, sizeof hostdir, dir.beg),
+			  fmtres.range.min, fmtres.range.max);
     }
 
   /* Has the likely and maximum directive output exceeded INT_MAX?  */
@@ -2928,30 +2933,25 @@ format_directive (const sprintf_dom_walk
 
       if (fmtres.range.min == fmtres.range.max)
 	warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
-			  "%<%.*s%> directive output of %wu bytes causes "
-			  "result to exceed %<INT_MAX%>",
-			  dirlen,
+			  G_("%<%.*s%> directive output of %wu bytes causes "
+			     "result to exceed %<INT_MAX%>"), dirlen,
 			  target_to_host (hostdir, sizeof hostdir, dir.beg),
 			  fmtres.range.min);
       else
-	{
-	  const char *fmtstr
-	    = (fmtres.range.min > target_int_max ()
-	       ? G_ ("%<%.*s%> directive output between %wu and %wu "
-		     "bytes causes result to exceed %<INT_MAX%>")
-	       : G_ ("%<%.*s%> directive output between %wu and %wu "
-		     "bytes may cause result to exceed %<INT_MAX%>"));
-	  warned = fmtwarn (dirloc, argloc, NULL,
-			    info.warnopt (), fmtstr, dirlen,
-			    target_to_host (hostdir, sizeof hostdir, dir.beg),
-			    fmtres.range.min, fmtres.range.max);
-	}
+	warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
+			  fmtres.range.min > target_int_max ()
+			  ? G_ ("%<%.*s%> directive output between %wu and "
+				"%wu bytes causes result to exceed "
+				"%<INT_MAX%>")
+			  : G_ ("%<%.*s%> directive output between %wu and "
+				"%wu bytes may cause result to exceed "
+				"%<INT_MAX%>"), dirlen,
+			  target_to_host (hostdir, sizeof hostdir, dir.beg),
+			  fmtres.range.min, fmtres.range.max);
     }
 
   if (warned && fmtres.range.min < fmtres.range.likely
       && 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,
 	      "assuming directive output of %wu byte",
 	      "assuming directive output of %wu bytes",
@@ -3022,8 +3022,6 @@ format_directive (const sprintf_dom_walk
   return true;
 }
 
-#pragma GCC diagnostic pop
-
 /* Parse a format directive in function call described by INFO starting
    at STR and populate DIR structure.  Bump up *ARGNO by the number of
    arguments extracted for the directive.  Return the length of
@@ -3373,9 +3371,10 @@ parse_directive (sprintf_dom_walker::cal
 	  substring_loc dirloc (info.fmtloc, TREE_TYPE (info.format),
 				caret, begin, end);
 
-	  fmtwarn (dirloc, UNKNOWN_LOCATION, NULL,
-		   info.warnopt (), "%<%.*s%> directive width out of range",
-		   dir.len, target_to_host (hostdir, sizeof hostdir, dir.beg));
+	  fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
+		   G_("%<%.*s%> directive width out of range"),
+		   (int) dir.len,
+		   target_to_host (hostdir, sizeof hostdir, dir.beg));
 	}
 
       dir.set_width (width);
@@ -3407,9 +3406,10 @@ parse_directive (sprintf_dom_walker::cal
 	  substring_loc dirloc (info.fmtloc, TREE_TYPE (info.format),
 				caret, begin, end);
 
-	  fmtwarn (dirloc, UNKNOWN_LOCATION, NULL,
-		   info.warnopt (), "%<%.*s%> directive precision out of range",
-		   dir.len, target_to_host (hostdir, sizeof hostdir, dir.beg));
+	  fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
+		   G_("%<%.*s%> directive precision out of range"),
+		   (int) dir.len,
+		   target_to_host (hostdir, sizeof hostdir, dir.beg));
 	}
 
       dir.set_precision (precision);

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]