From 9a80b5b98172638e1baae7b83ebbed80a2b67ce7 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 11 Sep 2018 00:38:47 +0100
Subject: [PATCH 03/11] FIXME: add format_string_diagnostic_t to reduce number
 of args (does this mess up gettext?)

---
 gcc/c-family/c-format.c   |  28 ++++++------
 gcc/gimple-ssa-sprintf.c  |  14 +++---
 gcc/substring-locations.c | 113 +++++++++++++++++++++++-----------------------
 gcc/substring-locations.h |  74 +++++++++++++++---------------
 4 files changed, 114 insertions(+), 115 deletions(-)

diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index 98c49cf5d18..a7edfca4aa9 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -100,8 +100,9 @@ format_warning_at_char (location_t fmt_string_loc, tree format_string_cst,
 
   substring_loc fmt_loc (fmt_string_loc, string_type, char_idx, char_idx,
 			 char_idx);
-  bool warned = format_warning_va (fmt_loc, NULL, UNKNOWN_LOCATION, NULL,
-				   NULL, opt, gmsgid, &ap);
+  format_string_diagnostic_t diag (fmt_loc, NULL, UNKNOWN_LOCATION, NULL,
+				   NULL);
+  bool warned = diag.emit_warning_va (opt, gmsgid, &ap);
   va_end (ap);
 
   return warned;
@@ -3694,13 +3695,13 @@ format_type_warning (const substring_loc &whole_fmt_loc,
   char *corrected_substring
     = get_corrected_substring (fmt_loc, type, arg_type, fki,
 			       offset_to_type_start, conversion_char);
-
+  format_string_diagnostic_t diag (fmt_loc, &fmt_label, param_loc, &param_label,
+				   corrected_substring);
   if (wanted_type_name)
     {
       if (arg_type)
-	format_warning_at_substring
-	  (fmt_loc, &fmt_label, param_loc, &param_label,
-	   corrected_substring, OPT_Wformat_,
+	diag.emit_warning
+	  (OPT_Wformat_,
 	   "%s %<%s%.*s%> expects argument of type %<%s%s%>, "
 	   "but argument %d has type %qT",
 	   gettext (kind_descriptions[kind]),
@@ -3708,9 +3709,8 @@ format_type_warning (const substring_loc &whole_fmt_loc,
 	   format_length, format_start,
 	   wanted_type_name, p, arg_num, arg_type);
       else
-	format_warning_at_substring
-	  (fmt_loc, &fmt_label, param_loc, &param_label,
-	   corrected_substring, OPT_Wformat_,
+	diag.emit_warning
+	  (OPT_Wformat_,
 	   "%s %<%s%.*s%> expects a matching %<%s%s%> argument",
 	   gettext (kind_descriptions[kind]),
 	   (kind == CF_KIND_FORMAT ? "%" : ""),
@@ -3719,9 +3719,8 @@ format_type_warning (const substring_loc &whole_fmt_loc,
   else
     {
       if (arg_type)
-	format_warning_at_substring
-	  (fmt_loc, &fmt_label, param_loc, &param_label,
-	   corrected_substring, OPT_Wformat_,
+	diag.emit_warning
+	  (OPT_Wformat_,
 	   "%s %<%s%.*s%> expects argument of type %<%T%s%>, "
 	   "but argument %d has type %qT",
 	   gettext (kind_descriptions[kind]),
@@ -3729,9 +3728,8 @@ format_type_warning (const substring_loc &whole_fmt_loc,
 	   format_length, format_start,
 	   wanted_type, p, arg_num, arg_type);
       else
-	format_warning_at_substring
-	  (fmt_loc, &fmt_label, param_loc, &param_label,
-	   corrected_substring, OPT_Wformat_,
+	diag.emit_warning
+	  (OPT_Wformat_,
 	   "%s %<%s%.*s%> expects a matching %<%T%s%> argument",
 	   gettext (kind_descriptions[kind]),
 	   (kind == CF_KIND_FORMAT ? "%" : ""),
diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c
index 91e21af2093..b6f317728c2 100644
--- a/gcc/gimple-ssa-sprintf.c
+++ b/gcc/gimple-ssa-sprintf.c
@@ -454,6 +454,7 @@ get_format_string (tree format, location_t *ploc)
   return c_getstr (format);
 }
 
+// FIXME
 /* For convenience and brevity, shorter named entrypoints of
    format_warning_at_substring and format_warning_at_substring_n.
    These have to be functions with the attribute so that exgettext
@@ -464,10 +465,11 @@ ATTRIBUTE_GCC_DIAG (5, 6)
 fmtwarn (const substring_loc &fmt_loc, location_t param_loc,
 	 const char *corrected_substring, int opt, const char *gmsgid, ...)
 {
+  format_string_diagnostic_t diag (fmt_loc, NULL, param_loc, NULL,
+				   corrected_substring);
   va_list ap;
   va_start (ap, gmsgid);
-  bool warned = format_warning_va (fmt_loc, NULL, param_loc, NULL,
-				   corrected_substring, opt, gmsgid, &ap);
+  bool warned = diag.emit_warning_va (opt, gmsgid, &ap);
   va_end (ap);
 
   return warned;
@@ -479,12 +481,12 @@ fmtwarn_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, ...)
 {
+  format_string_diagnostic_t diag (fmt_loc, NULL, param_loc, NULL,
+				   corrected_substring);
   va_list ap;
   va_start (ap, plural_gmsgid);
-  bool warned = format_warning_n_va (fmt_loc, NULL, param_loc, NULL,
-				     corrected_substring,
-				     opt, n, singular_gmsgid, plural_gmsgid,
-				     &ap);
+  bool warned = diag.emit_warning_n_va (opt, n, singular_gmsgid, plural_gmsgid,
+					&ap);
   va_end (ap);
 
   return warned;
diff --git a/gcc/substring-locations.c b/gcc/substring-locations.c
index faf78845840..db88f204801 100644
--- a/gcc/substring-locations.c
+++ b/gcc/substring-locations.c
@@ -28,12 +28,10 @@ along with GCC; see the file COPYING3.  If not see
 #include "substring-locations.h"
 #include "gcc-rich-location.h"
 
-/* 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.
+/* format_string_diagnostic_t's ctor, giving information for use by
+   the emit_warning* member functions, as follows:
 
-   Attempt to obtain precise location information within a string
+   They attempt to obtain precise location information within a string
    literal from FMT_LOC.
 
    Case 1: if substring location is available, and is within the range of
@@ -49,7 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 
    Case 2: if the substring location is available, but is not within
    the range of the format string, the primary location is that of the
-   format string, and an note is emitted showing the substring location.
+   format string, and a note is emitted showing the substring location.
 
    For example:
      test.c:90:10: warning: problem with '%i' here [-Wformat=]
@@ -120,29 +118,47 @@ along with GCC; see the file COPYING3.  If not see
                     ~^
                     %s
 
+*/
+
+format_string_diagnostic_t::
+format_string_diagnostic_t (const substring_loc &fmt_loc,
+			    const range_label *fmt_label,
+			    location_t param_loc,
+			    const range_label *param_label,
+			    const char *corrected_substring)
+: m_fmt_loc (fmt_loc),
+  m_fmt_label (fmt_label),
+  m_param_loc (param_loc),
+  m_param_label (param_label),
+  m_corrected_substring (corrected_substring)
+{
+}
+
+/* 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.
+
    Return true if a warning was emitted, false otherwise.  */
 
 bool
-format_warning_n_va (const substring_loc &fmt_loc,
-		     const range_label *fmt_label,
-		     location_t param_loc,
-		     const range_label *param_label,
-		     const char *corrected_substring,
-		     int opt, unsigned HOST_WIDE_INT n,
-		     const char *singular_gmsgid,
-		     const char *plural_gmsgid, va_list *ap)
+format_string_diagnostic_t::emit_warning_n_va (int opt,
+					       unsigned HOST_WIDE_INT n,
+					       const char *singular_gmsgid,
+					       const char *plural_gmsgid,
+					       va_list *ap) const
 {
   bool substring_within_range = false;
   location_t primary_loc;
   location_t fmt_substring_loc = UNKNOWN_LOCATION;
   source_range fmt_loc_range
-    = get_range_from_loc (line_table, fmt_loc.get_fmt_string_loc ());
-  const char *err = fmt_loc.get_location (&fmt_substring_loc);
+    = get_range_from_loc (line_table, m_fmt_loc.get_fmt_string_loc ());
+  const char *err = m_fmt_loc.get_location (&fmt_substring_loc);
   source_range fmt_substring_range
     = get_range_from_loc (line_table, fmt_substring_loc);
   if (err)
     /* Case 3: unable to get substring location.  */
-    primary_loc = fmt_loc.get_fmt_string_loc ();
+    primary_loc = m_fmt_loc.get_fmt_string_loc ();
   else
     {
       if (fmt_substring_range.m_start >= fmt_loc_range.m_start
@@ -158,23 +174,23 @@ format_warning_n_va (const substring_loc &fmt_loc,
 	/* Case 2.  */
 	{
 	  substring_within_range = false;
-	  primary_loc = fmt_loc.get_fmt_string_loc ();
+	  primary_loc = m_fmt_loc.get_fmt_string_loc ();
 	}
     }
 
   /* Only use fmt_label in the initial warning for case 1.  */
   const range_label *primary_label = NULL;
   if (substring_within_range)
-    primary_label = fmt_label;
+    primary_label = m_fmt_label;
 
   auto_diagnostic_group d;
   gcc_rich_location richloc (primary_loc, primary_label);
 
-  if (param_loc != UNKNOWN_LOCATION)
-    richloc.add_range (param_loc, SHOW_RANGE_WITHOUT_CARET, param_label);
+  if (m_param_loc != UNKNOWN_LOCATION)
+    richloc.add_range (m_param_loc, SHOW_RANGE_WITHOUT_CARET, m_param_label);
 
-  if (!err && corrected_substring && substring_within_range)
-    richloc.add_fixit_replace (fmt_substring_range, corrected_substring);
+  if (!err && m_corrected_substring && substring_within_range)
+    richloc.add_fixit_replace (fmt_substring_range, m_corrected_substring);
 
   diagnostic_info diagnostic;
   if (singular_gmsgid != plural_gmsgid)
@@ -205,10 +221,10 @@ format_warning_n_va (const substring_loc &fmt_loc,
       {
 	/* Use fmt_label in the note for case 2.  */
 	rich_location substring_richloc (line_table, fmt_substring_loc,
-					 fmt_label);
-	if (corrected_substring)
+					 m_fmt_label);
+	if (m_corrected_substring)
 	  substring_richloc.add_fixit_replace (fmt_substring_range,
-					       corrected_substring);
+					       m_corrected_substring);
 	inform (&substring_richloc,
 		"format string is defined here");
       }
@@ -219,55 +235,38 @@ format_warning_n_va (const substring_loc &fmt_loc,
 /* Singular-only version of the above.  */
 
 bool
-format_warning_va (const substring_loc &fmt_loc,
-		   const range_label *fmt_label,
-		   location_t param_loc,
-		   const range_label *param_label,
-		   const char *corrected_substring,
-		   int opt, const char *gmsgid, va_list *ap)
+format_string_diagnostic_t::emit_warning_va (int opt, const char *gmsgid,
+					     va_list *ap) const
 {
-  return format_warning_n_va (fmt_loc, fmt_label, param_loc, param_label,
-			      corrected_substring, opt,
-			      0, gmsgid, gmsgid, ap);
+  return emit_warning_n_va (opt, 0, gmsgid, gmsgid, ap);
 }
 
-/* Variadic call to format_warning_va.  */
+/* Variadic version of the above (singular only).  */
 
 bool
-format_warning_at_substring (const substring_loc &fmt_loc,
-			     const range_label *fmt_label,
-			     location_t param_loc,
-			     const range_label *param_label,
-			     const char *corrected_substring,
-			     int opt, const char *gmsgid, ...)
+format_string_diagnostic_t::emit_warning (int opt, const char *gmsgid,
+					  ...) const
 {
   va_list ap;
   va_start (ap, gmsgid);
-  bool warned = format_warning_va (fmt_loc, fmt_label, param_loc, param_label,
-				   corrected_substring, opt, gmsgid, &ap);
+  bool warned = emit_warning_va (opt, gmsgid, &ap);
   va_end (ap);
 
   return warned;
 }
 
-/* Variadic call to format_warning_n_va.  */
+/* Variadic version of the above (singular vs plural).  */
 
 bool
-format_warning_at_substring_n (const substring_loc &fmt_loc,
-			       const range_label *fmt_label,
-			       location_t param_loc,
-			       const range_label *param_label,
-			       const char *corrected_substring,
-			       int opt, unsigned HOST_WIDE_INT n,
-			       const char *singular_gmsgid,
-			       const char *plural_gmsgid, ...)
+format_string_diagnostic_t::emit_warning_n (int opt, unsigned HOST_WIDE_INT n,
+					    const char *singular_gmsgid,
+					    const char *plural_gmsgid,
+					    ...) const
 {
   va_list ap;
   va_start (ap, plural_gmsgid);
-  bool warned = format_warning_n_va (fmt_loc, fmt_label, param_loc, param_label,
-				     corrected_substring,
-				     opt, n, singular_gmsgid, plural_gmsgid,
-				     &ap);
+  bool warned = emit_warning_n_va (opt, n, singular_gmsgid, plural_gmsgid,
+				   &ap);
   va_end (ap);
 
   return warned;
diff --git a/gcc/substring-locations.h b/gcc/substring-locations.h
index 919fdf0127d..caac5376aeb 100644
--- a/gcc/substring-locations.h
+++ b/gcc/substring-locations.h
@@ -74,43 +74,43 @@ class substring_loc
   int m_end_idx;
 };
 
-/* Functions for emitting a warning about a format string.  */
-
-extern bool format_warning_va (const substring_loc &fmt_loc,
-			       const range_label *fmt_label,
-			       location_t param_loc,
-			       const range_label *param_label,
-			       const char *corrected_substring,
-			       int opt, const char *gmsgid, va_list *ap)
-  ATTRIBUTE_GCC_DIAG (7, 0);
-
-extern bool format_warning_n_va (const substring_loc &fmt_loc,
-				 const range_label *fmt_label,
-				 location_t param_loc,
-				 const range_label *param_label,
-				 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 (8, 0) ATTRIBUTE_GCC_DIAG (9, 0);
-
-extern bool format_warning_at_substring (const substring_loc &fmt_loc,
-					 const range_label *fmt_label,
-					 location_t param_loc,
-					 const range_label *param_label,
-					 const char *corrected_substring,
-					 int opt, const char *gmsgid, ...)
-  ATTRIBUTE_GCC_DIAG (7, 8);
-
-extern bool format_warning_at_substring_n (const substring_loc &fmt_loc,
-					   const range_label *fmt_label,
-					   location_t param_loc,
-					   const range_label *param_label,
-					   const char *corrected_substring,
-					   int opt, unsigned HOST_WIDE_INT n,
-					   const char *singular_gmsgid,
-					   const char *plural_gmsgid, ...)
-  ATTRIBUTE_GCC_DIAG (8, 10) ATTRIBUTE_GCC_DIAG (9, 10);
+/* A bundle of state for emitting a diagnostic relating to a format string.  */
+
+class format_string_diagnostic_t
+{
+ public:
+  format_string_diagnostic_t (const substring_loc &fmt_loc,
+			      const range_label *fmt_label,
+			      location_t param_loc,
+			      const range_label *param_label,
+			      const char *corrected_substring);
+
+  /* Functions for emitting a warning about a format string.  */
+
+  bool emit_warning_va (int opt, const char *gmsgid, va_list *ap) const
+    ATTRIBUTE_GCC_DIAG (3, 0);
+
+  bool emit_warning_n_va (int opt, unsigned HOST_WIDE_INT n,
+			  const char *singular_gmsgid,
+			  const char *plural_gmsgid, va_list *ap) const
+  ATTRIBUTE_GCC_DIAG (4, 0) ATTRIBUTE_GCC_DIAG (5, 0);
+
+  bool emit_warning (int opt, const char *gmsgid, ...) const
+    ATTRIBUTE_GCC_DIAG (3, 4);
+
+  bool emit_warning_n (int opt, unsigned HOST_WIDE_INT n,
+		       const char *singular_gmsgid,
+		       const char *plural_gmsgid, ...) const
+  ATTRIBUTE_GCC_DIAG (4, 6) ATTRIBUTE_GCC_DIAG (5, 6);
+
+ private:
+  const substring_loc &m_fmt_loc;
+  const range_label *m_fmt_label;
+  location_t m_param_loc;
+  const range_label *m_param_label;
+  const char *m_corrected_substring;
+};
+
 
 /* Implementation detail, for use when implementing
    LANG_HOOKS_GET_SUBSTRING_LOCATION.  */
-- 
2.13.6

