public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [committed] Add diagnostic_metadata and CWE support
@ 2019-12-19  0:10 David Malcolm
  2020-01-28 10:40 ` Jakub Jelinek
  0 siblings, 1 reply; 7+ messages in thread
From: David Malcolm @ 2019-12-19  0:10 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

This patch adds support for associating a diagnostic message with an
optional diagnostic_metadata object, so that plugins can add extra data
to their diagnostics (e.g. mapping a diagnostic to a taxonomy or coding
standard such as from CERT or MISRA).

Currently this only supports associating a CWE identifier with a
diagnostic (which is what I'm using for the warnings in the analyzer
patch kit), but adding a diagnostic_metadata class allows for future
growth in this area without an explosion of further "warning_at"
overloads for all of the different kinds of custom data that a plugin
might want to add.

This version of the patch renames the overly-general
-fdiagnostics-show-metadata to -fdiagnostics-show-cwe and adds test
coverage for it via a plugin.

It also adds a note to the documentation that no GCC diagnostics
currently use this; it's a feature for plugins (and, at some point,
I hope, the analyzer).

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.

Committed to trunk as r279556.

I've also pushed an incremental version of this patch relative to
  https://gcc.gnu.org/ml/gcc-patches/2019-12/msg00998.html
to dmalcolm/analyzer on the GCC git mirror, which also successfully
bootstrapped & regrtested on x86_64-pc-linux-gnu.

Dave

gcc/ChangeLog:
	* common.opt (fdiagnostics-show-cwe): Add.
	* diagnostic-core.h (class diagnostic_metadata): New forward decl.
	(warning_at): Add overload taking a const diagnostic_metadata &.
	(emit_diagnostic_valist): Add overload taking a
	const diagnostic_metadata *.
	* diagnostic-format-json.cc: Include "diagnostic-metadata.h".
	(json_from_metadata): New function.
	(json_end_diagnostic): Call it to add "metadata" child for
	diagnostics with metadata.
	(diagnostic_output_format_init): Clear context->show_cwe.
	* diagnostic-metadata.h: New file.
	* diagnostic.c: Include "diagnostic-metadata.h".
	(diagnostic_impl): Add const diagnostic_metadata * param.
	(diagnostic_n_impl): Likewise.
	(diagnostic_initialize): Initialize context->show_cwe.
	(diagnostic_set_info_translated): Initialize diagnostic->metadata.
	(get_cwe_url): New function.
	(print_any_cwe): New function.
	(diagnostic_report_diagnostic): Call print_any_cwe if the
	diagnostic has non-NULL metadata.
	(emit_diagnostic): Pass NULL as the metadata in the call to
	diagnostic_impl.
	(emit_diagnostic_valist): Likewise.
	(emit_diagnostic_valist): New overload taking a
	const diagnostic_metadata *.
	(inform): Pass NULL as the metadata in the call to
	diagnostic_impl.
	(inform_n): Likewise for diagnostic_n_impl.
	(warning): Likewise.
	(warning_at): Likewise.  Add overload that takes a
	const diagnostic_metadata &.
	(warning_n): Pass NULL as the metadata in the call to
	diagnostic_n_impl.
	(pedwarn): Likewise for diagnostic_impl.
	(permerror): Likewise.
	(error): Likewise.
	(error_n): Likewise.
	(error_at): Likewise.
	(sorry): Likewise.
	(sorry_at): Likewise.
	(fatal_error): Likewise.
	(internal_error): Likewise.
	(internal_error_no_backtrace): Likewise.
	* diagnostic.h (diagnostic_info::metadata): New field.
	(diagnostic_context::show_cwe): New field.
	* doc/invoke.texi (-fno-diagnostics-show-cwe): New option.
	* opts.c (common_handle_option): Handle OPT_fdiagnostics_show_cwe.
	* toplev.c (general_init): Initialize global_dc->show_cwe.

gcc/testsuite/ChangeLog:
	* gcc.dg/plugin/diagnostic-test-metadata.c: New test.
	* gcc.dg/plugin/diagnostic_plugin_test_metadata.c: New test plugin.
	* gcc.dg/plugin/plugin.exp (plugin_test_list): Add them.
---
 gcc/common.opt                                |   4 +
 gcc/diagnostic-core.h                         |  10 ++
 gcc/diagnostic-format-json.cc                 |  24 +++
 gcc/diagnostic-metadata.h                     |  42 ++++++
 gcc/diagnostic.c                              | 142 ++++++++++++++----
 gcc/diagnostic.h                              |   8 +
 gcc/doc/invoke.texi                           |  10 ++
 gcc/opts.c                                    |   4 +
 .../gcc.dg/plugin/diagnostic-test-metadata.c  |   9 ++
 .../plugin/diagnostic_plugin_test_metadata.c  | 140 +++++++++++++++++
 gcc/testsuite/gcc.dg/plugin/plugin.exp        |   1 +
 gcc/toplev.c                                  |   2 +
 12 files changed, 365 insertions(+), 31 deletions(-)
 create mode 100644 gcc/diagnostic-metadata.h
 create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata.c
 create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.c

diff --git a/gcc/common.opt b/gcc/common.opt
index b4dc31c7490..058da8af877 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1334,6 +1334,10 @@ fdiagnostics-show-option
 Common Var(flag_diagnostics_show_option) Init(1)
 Amend appropriate diagnostic messages with the command line option that controls them.
 
+fdiagnostics-show-cwe
+Common Var(flag_diagnostics_show_cwe) Init(1)
+Print CWE identifiers for diagnostic messages, where available.
+
 fdiagnostics-minimum-margin-width=
 Common Joined UInteger Var(diagnostics_minimum_margin_width) Init(6)
 Set minimum width of left margin of source code when showing source.
diff --git a/gcc/diagnostic-core.h b/gcc/diagnostic-core.h
index efafde4fa24..2e7f12070fb 100644
--- a/gcc/diagnostic-core.h
+++ b/gcc/diagnostic-core.h
@@ -45,6 +45,9 @@ class auto_diagnostic_group
   ~auto_diagnostic_group ();
 };
 
+/* Forward decl.  */
+class diagnostic_metadata; /* See diagnostic-metadata.h.  */
+
 extern const char *progname;
 
 extern const char *trim_filename (const char *);
@@ -78,6 +81,9 @@ 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 bool warning_at (rich_location *, const diagnostic_metadata &, int,
+			const char *, ...)
+    ATTRIBUTE_GCC_DIAG(4,5);
 extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
 extern void error_n (location_t, unsigned HOST_WIDE_INT, const char *,
 		     const char *, ...)
@@ -109,6 +115,10 @@ extern bool emit_diagnostic (diagnostic_t, rich_location *, int,
 			     const char *, ...) ATTRIBUTE_GCC_DIAG(4,5);
 extern bool emit_diagnostic_valist (diagnostic_t, location_t, int, const char *,
 				    va_list *) ATTRIBUTE_GCC_DIAG (4,0);
+extern bool emit_diagnostic_valist (diagnostic_t, rich_location *,
+				    const diagnostic_metadata *metadata,
+				    int, const char *, va_list *)
+  ATTRIBUTE_GCC_DIAG (5,0);
 extern bool seen_error (void);
 
 #ifdef BUFSIZ
diff --git a/gcc/diagnostic-format-json.cc b/gcc/diagnostic-format-json.cc
index 6782ec9dffb..18f7a56a8db 100644
--- a/gcc/diagnostic-format-json.cc
+++ b/gcc/diagnostic-format-json.cc
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "diagnostic.h"
+#include "diagnostic-metadata.h"
 #include "json.h"
 #include "selftest.h"
 
@@ -103,6 +104,20 @@ json_from_fixit_hint (const fixit_hint *hint)
   return fixit_obj;
 }
 
+/* Generate a JSON object for METADATA.  */
+
+static json::object *
+json_from_metadata (const diagnostic_metadata *metadata)
+{
+  json::object *metadata_obj = new json::object ();
+
+  if (metadata->get_cwe ())
+    metadata_obj->set ("cwe",
+		       new json::integer_number (metadata->get_cwe ()));
+
+  return metadata_obj;
+}
+
 /* No-op implementation of "begin_diagnostic" for JSON output.  */
 
 static void
@@ -211,6 +226,12 @@ json_end_diagnostic (diagnostic_context *context, diagnostic_info *diagnostic,
      TODO: functions
      TODO: inlining information
      TODO: macro expansion information.  */
+
+  if (diagnostic->metadata)
+    {
+      json::object *metadata_obj = json_from_metadata (diagnostic->metadata);
+      diag_obj->set ("metadata", metadata_obj);
+    }
 }
 
 /* No-op implementation of "begin_group_cb" for JSON output.  */
@@ -268,6 +289,9 @@ diagnostic_output_format_init (diagnostic_context *context,
 	context->end_group_cb =  json_end_group;
 	context->final_cb =  json_final_cb;
 
+	/* The metadata is handled in JSON format, rather than as text.  */
+	context->show_cwe = false;
+
 	/* The option is handled in JSON format, rather than as text.  */
 	context->show_option_requested = false;
 
diff --git a/gcc/diagnostic-metadata.h b/gcc/diagnostic-metadata.h
new file mode 100644
index 00000000000..a759d44fa44
--- /dev/null
+++ b/gcc/diagnostic-metadata.h
@@ -0,0 +1,42 @@
+/* Additional metadata for a diagnostic.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   Contributed by David Malcolm <dmalcolm@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_DIAGNOSTIC_METADATA_H
+#define GCC_DIAGNOSTIC_METADATA_H
+
+/* A bundle of additional metadata that can be associated with a
+   diagnostic.
+
+   Currently this only supports associating a CWE identifier with a
+   diagnostic.  */
+
+class diagnostic_metadata
+{
+ public:
+  diagnostic_metadata () : m_cwe (0) {}
+
+  void add_cwe (int cwe) { m_cwe = cwe; }
+  int get_cwe () const { return m_cwe; }
+
+ private:
+  int m_cwe;
+};
+
+#endif /* ! GCC_DIAGNOSTIC_METADATA_H */
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index d6604e6fd41..95cfb6e76ac 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic.h"
 #include "diagnostic-color.h"
 #include "diagnostic-url.h"
+#include "diagnostic-metadata.h"
 #include "edit-context.h"
 #include "selftest.h"
 #include "selftest-diagnostic.h"
@@ -58,11 +59,13 @@ along with GCC; see the file COPYING3.  If not see
 #define permissive_error_option(DC) ((DC)->opt_permissive)
 
 /* 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, unsigned HOST_WIDE_INT,
+static bool diagnostic_impl (rich_location *, const diagnostic_metadata *,
+			     int, const char *,
+			     va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(4,0);
+static bool diagnostic_n_impl (rich_location *, const diagnostic_metadata *,
+			       int, unsigned HOST_WIDE_INT,
 			       const char *, const char *, va_list *,
-			       diagnostic_t) ATTRIBUTE_GCC_DIAG(5,0);
+			       diagnostic_t) ATTRIBUTE_GCC_DIAG(6,0);
 
 static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN;
 static void real_abort (void) ATTRIBUTE_NORETURN;
@@ -183,6 +186,7 @@ diagnostic_initialize (diagnostic_context *context, int n_opts)
   diagnostic_set_caret_max_width (context, pp_line_cutoff (context->printer));
   for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++)
     context->caret_chars[i] = '^';
+  context->show_cwe = false;
   context->show_option_requested = false;
   context->abort_on_error = false;
   context->show_column = false;
@@ -299,6 +303,7 @@ diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg,
   diagnostic->message.format_spec = msg;
   diagnostic->message.m_richloc = richloc;
   diagnostic->richloc = richloc;
+  diagnostic->metadata = NULL;
   diagnostic->kind = kind;
   diagnostic->option_index = 0;
 }
@@ -898,6 +903,47 @@ update_effective_level_from_pragmas (diagnostic_context *context,
   return diag_class;
 }
 
+/* Generate a URL string describing CWE.  The caller is responsible for
+   freeing the string.  */
+
+static char *
+get_cwe_url (int cwe)
+{
+  return xasprintf ("https://cwe.mitre.org/data/definitions/%i.html", cwe);
+}
+
+/* If DIAGNOSTIC has a CWE identifier, print it.
+
+   For example, if the diagnostic metadata associates it with CWE-119,
+   " [CWE-119]" will be printed, suitably colorized, and with a URL of a
+   description of the security issue.  */
+
+static void
+print_any_cwe (diagnostic_context *context,
+		    const diagnostic_info *diagnostic)
+{
+  if (diagnostic->metadata == NULL)
+    return;
+
+  int cwe = diagnostic->metadata->get_cwe ();
+  if (cwe)
+    {
+      pretty_printer *pp = context->printer;
+      char *saved_prefix = pp_take_prefix (context->printer);
+      pp_string (pp, " [");
+      pp_string (pp, colorize_start (pp_show_color (pp),
+				     diagnostic_kind_color[diagnostic->kind]));
+      char *cwe_url = get_cwe_url (cwe);
+      pp_begin_url (pp, cwe_url);
+      free (cwe_url);
+      pp_printf (pp, "CWE-%i", cwe);
+      pp_set_prefix (context->printer, saved_prefix);
+      pp_end_url (pp);
+      pp_string (pp, colorize_stop (pp_show_color (pp)));
+      pp_character (pp, ']');
+    }
+}
+
 /* Print any metadata about the option used to control DIAGNOSTIC to CONTEXT's
    printer, e.g. " [-Werror=uninitialized]".
    Subroutine of diagnostic_report_diagnostic.  */
@@ -1058,6 +1104,8 @@ diagnostic_report_diagnostic (diagnostic_context *context,
   pp_format (context->printer, &diagnostic->message);
   (*diagnostic_starter (context)) (context, diagnostic);
   pp_output_formatted_text (context->printer);
+  if (context->show_cwe)
+    print_any_cwe (context, diagnostic);
   if (context->show_option_requested)
     print_option_information (context, diagnostic, orig_diag_kind);
   (*diagnostic_finalizer (context)) (context, diagnostic, orig_diag_kind);
@@ -1183,8 +1231,8 @@ diagnostic_append_note (diagnostic_context *context,
    permerror, error, error_at, error_at, sorry, fatal_error, internal_error,
    and internal_error_no_backtrace, as documented and defined below.  */
 static bool
-diagnostic_impl (rich_location *richloc, int opt,
-		 const char *gmsgid,
+diagnostic_impl (rich_location *richloc, const diagnostic_metadata *metadata,
+		 int opt, const char *gmsgid,
 		 va_list *ap, diagnostic_t kind)
 {
   diagnostic_info diagnostic;
@@ -1200,13 +1248,15 @@ diagnostic_impl (rich_location *richloc, int opt,
       if (kind == DK_WARNING || kind == DK_PEDWARN)
 	diagnostic.option_index = opt;
     }
+  diagnostic.metadata = metadata;
   return diagnostic_report_diagnostic (global_dc, &diagnostic);
 }
 
 /* Implement inform_n, warning_n, and error_n, as documented and
    defined below.  */
 static bool
-diagnostic_n_impl (rich_location *richloc, int opt, unsigned HOST_WIDE_INT n,
+diagnostic_n_impl (rich_location *richloc, const diagnostic_metadata *metadata,
+		   int opt, unsigned HOST_WIDE_INT n,
 		   const char *singular_gmsgid,
 		   const char *plural_gmsgid,
 		   va_list *ap, diagnostic_t kind)
@@ -1226,6 +1276,7 @@ diagnostic_n_impl (rich_location *richloc, int opt, unsigned HOST_WIDE_INT n,
   diagnostic_set_info_translated (&diagnostic, text, ap, richloc, kind);
   if (kind == DK_WARNING)
     diagnostic.option_index = opt;
+  diagnostic.metadata = metadata;
   return diagnostic_report_diagnostic (global_dc, &diagnostic);
 }
 
@@ -1239,7 +1290,7 @@ emit_diagnostic (diagnostic_t kind, location_t location, int opt,
   va_list ap;
   va_start (ap, gmsgid);
   rich_location richloc (line_table, location);
-  bool ret = diagnostic_impl (&richloc, opt, gmsgid, &ap, kind);
+  bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, kind);
   va_end (ap);
   return ret;
 }
@@ -1253,7 +1304,7 @@ emit_diagnostic (diagnostic_t kind, rich_location *richloc, int opt,
   auto_diagnostic_group d;
   va_list ap;
   va_start (ap, gmsgid);
-  bool ret = diagnostic_impl (richloc, opt, gmsgid, &ap, kind);
+  bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, kind);
   va_end (ap);
   return ret;
 }
@@ -1265,7 +1316,18 @@ emit_diagnostic_valist (diagnostic_t kind, location_t location, int opt,
 			const char *gmsgid, va_list *ap)
 {
   rich_location richloc (line_table, location);
-  return diagnostic_impl (&richloc, opt, gmsgid, ap, kind);
+  return diagnostic_impl (&richloc, NULL, opt, gmsgid, ap, kind);
+}
+
+/* Wrapper around diagnostic_impl taking a va_list parameter.  */
+
+bool
+emit_diagnostic_valist (diagnostic_t kind, rich_location *richloc,
+			const diagnostic_metadata *metadata,
+			int opt,
+			const char *gmsgid, va_list *ap)
+{
+  return diagnostic_impl (richloc, metadata, opt, gmsgid, ap, kind);
 }
 
 /* An informative note at LOCATION.  Use this for additional details on an error
@@ -1277,7 +1339,7 @@ inform (location_t location, const char *gmsgid, ...)
   va_list ap;
   va_start (ap, gmsgid);
   rich_location richloc (line_table, location);
-  diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_NOTE);
+  diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_NOTE);
   va_end (ap);
 }
 
@@ -1290,7 +1352,7 @@ inform (rich_location *richloc, const char *gmsgid, ...)
   auto_diagnostic_group d;
   va_list ap;
   va_start (ap, gmsgid);
-  diagnostic_impl (richloc, -1, gmsgid, &ap, DK_NOTE);
+  diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_NOTE);
   va_end (ap);
 }
 
@@ -1304,7 +1366,7 @@ inform_n (location_t location, unsigned HOST_WIDE_INT n,
   va_start (ap, plural_gmsgid);
   auto_diagnostic_group d;
   rich_location richloc (line_table, location);
-  diagnostic_n_impl (&richloc, -1, n, singular_gmsgid, plural_gmsgid,
+  diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid,
 		     &ap, DK_NOTE);
   va_end (ap);
 }
@@ -1319,7 +1381,7 @@ warning (int opt, const char *gmsgid, ...)
   va_list ap;
   va_start (ap, gmsgid);
   rich_location richloc (line_table, input_location);
-  bool ret = diagnostic_impl (&richloc, opt, gmsgid, &ap, DK_WARNING);
+  bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
   va_end (ap);
   return ret;
 }
@@ -1335,7 +1397,7 @@ warning_at (location_t location, int opt, const char *gmsgid, ...)
   va_list ap;
   va_start (ap, gmsgid);
   rich_location richloc (line_table, location);
-  bool ret = diagnostic_impl (&richloc, opt, gmsgid, &ap, DK_WARNING);
+  bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
   va_end (ap);
   return ret;
 }
@@ -1350,7 +1412,25 @@ warning_at (rich_location *richloc, int opt, const char *gmsgid, ...)
   auto_diagnostic_group d;
   va_list ap;
   va_start (ap, gmsgid);
-  bool ret = diagnostic_impl (richloc, opt, gmsgid, &ap, DK_WARNING);
+  bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
+  va_end (ap);
+  return ret;
+}
+
+/* Same as "warning at" above, but using METADATA.  */
+
+bool
+warning_at (rich_location *richloc, const diagnostic_metadata &metadata,
+	    int opt, const char *gmsgid, ...)
+{
+  gcc_assert (richloc);
+
+  auto_diagnostic_group d;
+  va_list ap;
+  va_start (ap, gmsgid);
+  bool ret
+    = diagnostic_impl (richloc, &metadata, opt, gmsgid, &ap,
+		       DK_WARNING);
   va_end (ap);
   return ret;
 }
@@ -1366,7 +1446,7 @@ warning_n (rich_location *richloc, int opt, unsigned HOST_WIDE_INT n,
   auto_diagnostic_group d;
   va_list ap;
   va_start (ap, plural_gmsgid);
-  bool ret = diagnostic_n_impl (richloc, opt, n,
+  bool ret = diagnostic_n_impl (richloc, NULL, opt, n,
 				singular_gmsgid, plural_gmsgid,
 				&ap, DK_WARNING);
   va_end (ap);
@@ -1385,7 +1465,7 @@ warning_n (location_t location, int opt, unsigned HOST_WIDE_INT n,
   va_list ap;
   va_start (ap, plural_gmsgid);
   rich_location richloc (line_table, location);
-  bool ret = diagnostic_n_impl (&richloc, opt, n,
+  bool ret = diagnostic_n_impl (&richloc, NULL, opt, n,
 				singular_gmsgid, plural_gmsgid,
 				&ap, DK_WARNING);
   va_end (ap);
@@ -1412,7 +1492,7 @@ pedwarn (location_t location, int opt, const char *gmsgid, ...)
   va_list ap;
   va_start (ap, gmsgid);
   rich_location richloc (line_table, location);
-  bool ret = diagnostic_impl (&richloc, opt, gmsgid, &ap, DK_PEDWARN);
+  bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN);
   va_end (ap);
   return ret;
 }
@@ -1427,7 +1507,7 @@ pedwarn (rich_location *richloc, int opt, const char *gmsgid, ...)
   auto_diagnostic_group d;
   va_list ap;
   va_start (ap, gmsgid);
-  bool ret = diagnostic_impl (richloc, opt, gmsgid, &ap, DK_PEDWARN);
+  bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN);
   va_end (ap);
   return ret;
 }
@@ -1446,7 +1526,7 @@ permerror (location_t location, const char *gmsgid, ...)
   va_list ap;
   va_start (ap, gmsgid);
   rich_location richloc (line_table, location);
-  bool ret = diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_PERMERROR);
+  bool ret = diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR);
   va_end (ap);
   return ret;
 }
@@ -1461,7 +1541,7 @@ permerror (rich_location *richloc, const char *gmsgid, ...)
   auto_diagnostic_group d;
   va_list ap;
   va_start (ap, gmsgid);
-  bool ret = diagnostic_impl (richloc, -1, gmsgid, &ap, DK_PERMERROR);
+  bool ret = diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR);
   va_end (ap);
   return ret;
 }
@@ -1475,7 +1555,7 @@ error (const char *gmsgid, ...)
   va_list ap;
   va_start (ap, gmsgid);
   rich_location richloc (line_table, input_location);
-  diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_ERROR);
+  diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
   va_end (ap);
 }
 
@@ -1489,7 +1569,7 @@ error_n (location_t location, unsigned HOST_WIDE_INT n,
   va_list ap;
   va_start (ap, plural_gmsgid);
   rich_location richloc (line_table, location);
-  diagnostic_n_impl (&richloc, -1, n, singular_gmsgid, plural_gmsgid,
+  diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid,
 		     &ap, DK_ERROR);
   va_end (ap);
 }
@@ -1502,7 +1582,7 @@ error_at (location_t loc, const char *gmsgid, ...)
   va_list ap;
   va_start (ap, gmsgid);
   rich_location richloc (line_table, loc);
-  diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_ERROR);
+  diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
   va_end (ap);
 }
 
@@ -1516,7 +1596,7 @@ error_at (rich_location *richloc, const char *gmsgid, ...)
   auto_diagnostic_group d;
   va_list ap;
   va_start (ap, gmsgid);
-  diagnostic_impl (richloc, -1, gmsgid, &ap, DK_ERROR);
+  diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
   va_end (ap);
 }
 
@@ -1530,7 +1610,7 @@ sorry (const char *gmsgid, ...)
   va_list ap;
   va_start (ap, gmsgid);
   rich_location richloc (line_table, input_location);
-  diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_SORRY);
+  diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY);
   va_end (ap);
 }
 
@@ -1542,7 +1622,7 @@ sorry_at (location_t loc, const char *gmsgid, ...)
   va_list ap;
   va_start (ap, gmsgid);
   rich_location richloc (line_table, loc);
-  diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_SORRY);
+  diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY);
   va_end (ap);
 }
 
@@ -1564,7 +1644,7 @@ fatal_error (location_t loc, const char *gmsgid, ...)
   va_list ap;
   va_start (ap, gmsgid);
   rich_location richloc (line_table, loc);
-  diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_FATAL);
+  diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_FATAL);
   va_end (ap);
 
   gcc_unreachable ();
@@ -1581,7 +1661,7 @@ internal_error (const char *gmsgid, ...)
   va_list ap;
   va_start (ap, gmsgid);
   rich_location richloc (line_table, input_location);
-  diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_ICE);
+  diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE);
   va_end (ap);
 
   gcc_unreachable ();
@@ -1597,7 +1677,7 @@ internal_error_no_backtrace (const char *gmsgid, ...)
   va_list ap;
   va_start (ap, gmsgid);
   rich_location richloc (line_table, input_location);
-  diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_ICE_NOBT);
+  diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE_NOBT);
   va_end (ap);
 
   gcc_unreachable ();
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 91e4c509605..3a49c99e3af 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -46,6 +46,10 @@ struct diagnostic_info
   /* The location at which the diagnostic is to be reported.  */
   rich_location *richloc;
 
+  /* An optional bundle of metadata associated with the diagnostic
+     (or NULL).  */
+  const diagnostic_metadata *metadata;
+
   /* Auxiliary data for client.  */
   void *x_data;
   /* The kind of diagnostic it is about.  */
@@ -126,6 +130,10 @@ struct diagnostic_context
   /* Character used for caret diagnostics.  */
   char caret_chars[rich_location::STATICALLY_ALLOCATED_RANGES];
 
+  /* True if we should print any CWE identifiers associated with
+     diagnostics.  */
+  bool show_cwe;
+
   /* True if we should print the command line option which controls
      each diagnostic, if known.  */
   bool show_option_requested;
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 157dc907eec..6942881dbcc 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -277,6 +277,7 @@ Objective-C and Objective-C++ Dialects}.
 -fdiagnostics-format=@r{[}text@r{|}json@r{]}  @gol
 -fno-diagnostics-show-option  -fno-diagnostics-show-caret @gol
 -fno-diagnostics-show-labels  -fno-diagnostics-show-line-numbers @gol
+-fno-diagnostics-show-cwe  @gol
 -fdiagnostics-minimum-margin-width=@var{width} @gol
 -fdiagnostics-parseable-fixits  -fdiagnostics-generate-patch @gol
 -fdiagnostics-show-template-tree  -fno-elide-type @gol
@@ -3964,6 +3965,15 @@ as the types of expressions:
 This option suppresses the printing of these labels (in the example above,
 the vertical bars and the ``char *'' and ``long int'' text).
 
+@item -fno-diagnostics-show-cwe
+@opindex fno-diagnostics-show-cwe
+@opindex fdiagnostics-show-cwe
+Diagnostic messages can optionally have an associated
+@url{https://cwe.mitre.org/index.html, CWE} identifier.
+GCC itself does not do this for any of its diagnostics, but plugins may do so.
+By default, if this information is present, it will be printed with
+the diagnostic.  This option suppresses the printing of this metadata.
+
 @item -fno-diagnostics-show-line-numbers
 @opindex fno-diagnostics-show-line-numbers
 @opindex fdiagnostics-show-line-numbers
diff --git a/gcc/opts.c b/gcc/opts.c
index df6cc6495db..d4a98c8d942 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -2407,6 +2407,10 @@ common_handle_option (struct gcc_options *opts,
       dc->parseable_fixits_p = value;
       break;
 
+    case OPT_fdiagnostics_show_cwe:
+      dc->show_cwe = value;
+      break;
+
     case OPT_fdiagnostics_show_option:
       dc->show_option_requested = value;
       break;
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata.c
new file mode 100644
index 00000000000..d2babd35753
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+extern char *gets (char *s);
+
+void test_cwe (void)
+{
+  char buf[1024];
+  gets (buf); /* { dg-warning "never use 'gets' \\\[CWE-242\\\]" } */
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.c
new file mode 100644
index 00000000000..5e58115afba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.c
@@ -0,0 +1,140 @@
+/* This plugin exercises diagnostic_metadata.  */
+
+#include "gcc-plugin.h"
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "toplev.h"
+#include "basic-block.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "tree.h"
+#include "tree-pass.h"
+#include "intl.h"
+#include "plugin-version.h"
+#include "diagnostic.h"
+#include "context.h"
+#include "gcc-rich-location.h"
+#include "diagnostic-metadata.h"
+
+int plugin_is_GPL_compatible;
+
+const pass_data pass_data_test_metadata =
+{
+  GIMPLE_PASS, /* type */
+  "test_metadata", /* name */
+  OPTGROUP_NONE, /* optinfo_flags */
+  TV_NONE, /* tv_id */
+  PROP_ssa, /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  0, /* todo_flags_finish */
+};
+
+class pass_test_metadata : public gimple_opt_pass
+{
+public:
+  pass_test_metadata(gcc::context *ctxt)
+    : gimple_opt_pass(pass_data_test_metadata, ctxt)
+  {}
+
+  /* opt_pass methods: */
+  bool gate (function *) { return true; }
+  virtual unsigned int execute (function *);
+
+}; // class pass_test_metadata
+
+/* Determine if STMT is a call with NUM_ARGS arguments to a function
+   named FUNCNAME.
+   If so, return STMT as a gcall *.  Otherwise return NULL.  */
+
+static gcall *
+check_for_named_call (gimple *stmt,
+		      const char *funcname, unsigned int num_args)
+{
+  gcc_assert (funcname);
+
+  gcall *call = dyn_cast <gcall *> (stmt);
+  if (!call)
+    return NULL;
+
+  tree fndecl = gimple_call_fndecl (call);
+  if (!fndecl)
+    return NULL;
+
+  if (strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), funcname))
+    return NULL;
+
+  if (gimple_call_num_args (call) != num_args)
+    {
+      error_at (stmt->location, "expected number of args: %i (got %i)",
+		num_args, gimple_call_num_args (call));
+      return NULL;
+    }
+
+  return call;
+}
+
+/* Exercise diagnostic_metadata.  */
+
+unsigned int
+pass_test_metadata::execute (function *fun)
+{
+  gimple_stmt_iterator gsi;
+  basic_block bb;
+
+  FOR_EACH_BB_FN (bb, fun)
+    for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+      {
+	gimple *stmt = gsi_stmt (gsi);
+
+	/* Example of CWE: complain about uses of gets.  */
+	if (gcall *call = check_for_named_call (stmt, "gets", 1))
+	  {
+	    gcc_rich_location richloc (gimple_location (call));
+	    /* CWE-242: Use of Inherently Dangerous Function.  */
+	    diagnostic_metadata m;
+	    m.add_cwe (242);
+	    warning_at (&richloc, m, 0,
+			"never use %qs", "gets");
+	  }
+      }
+
+  return 0;
+}
+
+int
+plugin_init (struct plugin_name_args *plugin_info,
+	     struct plugin_gcc_version *version)
+{
+  struct register_pass_info pass_info;
+  const char *plugin_name = plugin_info->base_name;
+  int argc = plugin_info->argc;
+  struct plugin_argument *argv = plugin_info->argv;
+
+  if (!plugin_default_version_check (version, &gcc_version))
+    return 1;
+
+  pass_info.pass = new pass_test_metadata (g);
+  pass_info.reference_pass_name = "ssa";
+  pass_info.ref_pass_instance_number = 1;
+  pass_info.pos_op = PASS_POS_INSERT_AFTER;
+  register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
+		     &pass_info);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp
index 2f75463f3d8..439fbd7224f 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugin.exp
+++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp
@@ -94,6 +94,7 @@ set plugin_test_list [list \
 	  diagnostic-test-inlining-2.c \
 	  diagnostic-test-inlining-3.c \
 	  diagnostic-test-inlining-4.c } \
+    { diagnostic_plugin_test_metadata.c diagnostic-test-metadata.c } \
     { location_overflow_plugin.c \
 	  location-overflow-test-1.c \
 	  location-overflow-test-2.c \
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 059046f40f3..6f5b53aaac2 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1179,6 +1179,8 @@ general_init (const char *argv0, bool init_signals)
     = global_options_init.x_flag_diagnostics_show_labels;
   global_dc->show_line_numbers_p
     = global_options_init.x_flag_diagnostics_show_line_numbers;
+  global_dc->show_cwe
+    = global_options_init.x_flag_diagnostics_show_cwe;
   global_dc->show_option_requested
     = global_options_init.x_flag_diagnostics_show_option;
   global_dc->min_margin_width
-- 
2.21.0

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [committed] Add diagnostic_metadata and CWE support
  2019-12-19  0:10 [committed] Add diagnostic_metadata and CWE support David Malcolm
@ 2020-01-28 10:40 ` Jakub Jelinek
  2020-01-28 14:46   ` [PATCH] diagnostic_metadata: unbreak xgettext David Malcolm
  0 siblings, 1 reply; 7+ messages in thread
From: Jakub Jelinek @ 2020-01-28 10:40 UTC (permalink / raw)
  To: David Malcolm, Joseph S. Myers; +Cc: gcc-patches

On Wed, Dec 18, 2019 at 07:08:25PM -0500, David Malcolm wrote:
> This patch adds support for associating a diagnostic message with an
> optional diagnostic_metadata object, so that plugins can add extra data
> to their diagnostics (e.g. mapping a diagnostic to a taxonomy or coding
> standard such as from CERT or MISRA).
> 
> Currently this only supports associating a CWE identifier with a
> diagnostic (which is what I'm using for the warnings in the analyzer
> patch kit), but adding a diagnostic_metadata class allows for future
> growth in this area without an explosion of further "warning_at"
> overloads for all of the different kinds of custom data that a plugin
> might want to add.
> 
> This version of the patch renames the overly-general
> -fdiagnostics-show-metadata to -fdiagnostics-show-cwe and adds test
> coverage for it via a plugin.
> 
> It also adds a note to the documentation that no GCC diagnostics
> currently use this; it's a feature for plugins (and, at some point,
> I hope, the analyzer).
> 
> Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
> 
> Committed to trunk as r279556.

Unfortunately, this patch broke the i18n.
$ make gcc.pot
/bin/sh ../../gcc/../mkinstalldirs po
make srcextra
make[1]: Entering directory '/usr/src/gcc/obj/gcc'
cp -p gengtype-lex.c ../../gcc
cp -p gengtype-lex.c ../../gcc
make[1]: Leaving directory '/usr/src/gcc/obj/gcc'
AWK=gawk /bin/sh ../../gcc/po/exgettext \
	/usr/bin/xgettext gcc ../../gcc
scanning for keywords, %e and %n strings...
emit_diagnostic_valist used incompatibly as both --keyword=emit_diagnostic_valist:4
--flag=emit_diagnostic_valist:4:gcc-internal-format and --keyword=emit_diagnostic_valist:5
--flag=emit_diagnostic_valist:5:gcc-internal-format
make: *** [Makefile:4338: po/gcc.pot] Error 1

While C++ can have overloads, xgettext can't deal with overloads that have
different argument positions.
emit_diagnostic_valist with the new args (i.e. the :5 one) isn't used right
now, so one way around at least for now is to remove it again, another is to
rename it.

	Jakub

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] diagnostic_metadata: unbreak xgettext
  2020-01-28 10:40 ` Jakub Jelinek
@ 2020-01-28 14:46   ` David Malcolm
  2020-01-28 14:56     ` Jakub Jelinek
  0 siblings, 1 reply; 7+ messages in thread
From: David Malcolm @ 2020-01-28 14:46 UTC (permalink / raw)
  To: Jakub Jelinek, Joseph S . Myers; +Cc: gcc-patches, David Malcolm

On Tue, 2020-01-28 at 11:16 +0100, Jakub Jelinek wrote:
> On Wed, Dec 18, 2019 at 07:08:25PM -0500, David Malcolm wrote:
> > This patch adds support for associating a diagnostic message with
> > an
> > optional diagnostic_metadata object, so that plugins can add extra
> > data
> > to their diagnostics (e.g. mapping a diagnostic to a taxonomy or
> > coding
> > standard such as from CERT or MISRA).
> > 
> > Currently this only supports associating a CWE identifier with a
> > diagnostic (which is what I'm using for the warnings in the
> > analyzer
> > patch kit), but adding a diagnostic_metadata class allows for
> > future
> > growth in this area without an explosion of further "warning_at"
> > overloads for all of the different kinds of custom data that a
> > plugin
> > might want to add.
> > 
> > This version of the patch renames the overly-general
> > -fdiagnostics-show-metadata to -fdiagnostics-show-cwe and adds test
> > coverage for it via a plugin.
> > 
> > It also adds a note to the documentation that no GCC diagnostics
> > currently use this; it's a feature for plugins (and, at some point,
> > I hope, the analyzer).
> > 
> > Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
> > 
> > Committed to trunk as r279556.
> 
> Unfortunately, this patch broke the i18n.
> $ make gcc.pot
> /bin/sh ../../gcc/../mkinstalldirs po
> make srcextra
> make[1]: Entering directory '/usr/src/gcc/obj/gcc'
> cp -p gengtype-lex.c ../../gcc
> cp -p gengtype-lex.c ../../gcc
> make[1]: Leaving directory '/usr/src/gcc/obj/gcc'
> AWK=gawk /bin/sh ../../gcc/po/exgettext \
> 	/usr/bin/xgettext gcc ../../gcc
> scanning for keywords, %e and %n strings...
> emit_diagnostic_valist used incompatibly as both --
> keyword=emit_diagnostic_valist:4
> --flag=emit_diagnostic_valist:4:gcc-internal-format and --
> keyword=emit_diagnostic_valist:5
> --flag=emit_diagnostic_valist:5:gcc-internal-format
> make: *** [Makefile:4338: po/gcc.pot] Error 1
> 
> While C++ can have overloads, xgettext can't deal with overloads that
> have
> different argument positions.
> emit_diagnostic_valist with the new args (i.e. the :5 one) isn't used
> right
> now, so one way around at least for now is to remove it again,
> another is to
> rename it.
> 
> 	Jakub

Sorry about this.

There are actually two broken names; here's the patch I'm currently testing
(which fixes "make gcc.pot" for me); bootstrap is in progress:


While C++ can have overloads, xgettext can't deal with overloads that have
different argument positions, leading to two failures in "make gcc.pot":

emit_diagnostic_valist used incompatibly as both
--keyword=emit_diagnostic_valist:4
--flag=emit_diagnostic_valist:4:gcc-internal-format and
--keyword=emit_diagnostic_valist:5
--flag=emit_diagnostic_valist:5:gcc-internal-format

warning_at used incompatibly as both
--keyword=warning_at:3 --flag=warning_at:3:gcc-internal-format and
--keyword=warning_at:4 --flag=warning_at:4:gcc-internal-format

The emit_diagnostic_valist overload isn't used anywhere (I think it's
a leftover from an earlier iteration of the analyzer patch kit).

The warning_at overload is used throughout the analyzer but nowhere else.

Ideally I'd like to consolidate this argument with something
constructable in various ways:
- from a metadata and an int or
- from an int (or, better an "enum opt_code"),
so that the overload happens when implicitly choosing the ctor, but
that feels like stage 1 material.

In the meantime, fix xgettext by deleting the unused overload and
renaming the used one.

gcc/analyzer/ChangeLog:
	* region-model.cc (poisoned_value_diagnostic::emit): Update for
	renaming of warning_at overload to warning_with_metadata_at.
	* sm-file.cc (file_leak::emit): Likewise.
	* sm-malloc.cc (double_free::emit): Likewise.
	(possible_null_deref::emit): Likewise.
	(possible_null_arg::emit): Likewise.
	(null_deref::emit): Likewise.
	(null_arg::emit): Likewise.
	(use_after_free::emit): Likewise.
	(malloc_leak::emit): Likewise.
	(free_of_non_heap::emit): Likewise.
	* sm-sensitive.cc (exposure_through_output_file::emit): Likewise.
	* sm-signal.cc (signal_unsafe_call::emit): Likewise.
	* sm-taint.cc (tainted_array_index::emit): Likewise.

gcc/ChangeLog:
	* diagnostic-core.h (warning_at): Rename overload to...
	(warning_with_metadata_at): ...this.
	(emit_diagnostic_valist): Delete decl of overload taking
	diagnostic_metadata.
	* diagnostic.c (emit_diagnostic_valist): Likewise for defn.
	(warning_at): Rename overload taking diagnostic_metadata to...
	(warning_with_metadata_at): ...this.
---
 gcc/analyzer/region-model.cc | 24 ++++++++--------
 gcc/analyzer/sm-file.cc      |  6 ++--
 gcc/analyzer/sm-malloc.cc    | 54 ++++++++++++++++++++----------------
 gcc/analyzer/sm-sensitive.cc |  7 +++--
 gcc/analyzer/sm-signal.cc    |  8 +++---
 gcc/analyzer/sm-taint.cc     | 27 ++++++++++--------
 gcc/diagnostic-core.h        |  9 ++----
 gcc/diagnostic.c             | 16 ++---------
 8 files changed, 74 insertions(+), 77 deletions(-)

diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 62c96a6ceea..74602f1a66f 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -3827,30 +3827,30 @@ public:
 	{
 	  diagnostic_metadata m;
 	  m.add_cwe (457); /* "CWE-457: Use of Uninitialized Variable".  */
-	  return warning_at (rich_loc, m,
-			     OPT_Wanalyzer_use_of_uninitialized_value,
-			     "use of uninitialized value %qE",
-			     m_expr);
+	  return warning_with_metadata_at
+	    (rich_loc, m, OPT_Wanalyzer_use_of_uninitialized_value,
+	     "use of uninitialized value %qE",
+	     m_expr);
 	}
 	break;
       case POISON_KIND_FREED:
 	{
 	  diagnostic_metadata m;
 	  m.add_cwe (416); /* "CWE-416: Use After Free".  */
-	  return warning_at (rich_loc, m,
-			     OPT_Wanalyzer_use_after_free,
-			     "use after %<free%> of %qE",
-			     m_expr);
+	  return warning_with_metadata_at (rich_loc, m,
+					   OPT_Wanalyzer_use_after_free,
+					   "use after %<free%> of %qE",
+					   m_expr);
 	}
 	break;
       case POISON_KIND_POPPED_STACK:
 	{
 	  diagnostic_metadata m;
 	  /* TODO: which CWE?  */
-	  return warning_at (rich_loc, m,
-			     OPT_Wanalyzer_use_of_pointer_in_stale_stack_frame,
-			     "use of pointer %qE within stale stack frame",
-			     m_expr);
+	  return warning_with_metadata_at
+	    (rich_loc, m, OPT_Wanalyzer_use_of_pointer_in_stale_stack_frame,
+	     "use of pointer %qE within stale stack frame",
+	     m_expr);
 	}
 	break;
       }
diff --git a/gcc/analyzer/sm-file.cc b/gcc/analyzer/sm-file.cc
index 11444926538..695c50d8c31 100644
--- a/gcc/analyzer/sm-file.cc
+++ b/gcc/analyzer/sm-file.cc
@@ -178,9 +178,9 @@ public:
     /* CWE-775: "Missing Release of File Descriptor or Handle after
        Effective Lifetime". */
     m.add_cwe (775);
-    return warning_at (rich_loc, m, OPT_Wanalyzer_file_leak,
-		       "leak of FILE %qE",
-		       m_arg);
+    return warning_with_metadata_at (rich_loc, m, OPT_Wanalyzer_file_leak,
+				     "leak of FILE %qE",
+				     m_arg);
   }
 
   label_text describe_state_change (const evdesc::state_change &change)
diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc
index 526680accf2..54fba26ac6c 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -145,8 +145,8 @@ public:
     auto_diagnostic_group d;
     diagnostic_metadata m;
     m.add_cwe (415); /* CWE-415: Double Free.  */
-    return warning_at (rich_loc, m, OPT_Wanalyzer_double_free,
-		       "double-%<free%> of %qE", m_arg);
+    return warning_with_metadata_at (rich_loc, m, OPT_Wanalyzer_double_free,
+				     "double-%<free%> of %qE", m_arg);
   }
 
   label_text describe_state_change (const evdesc::state_change &change)
@@ -235,8 +235,9 @@ public:
     /* CWE-690: Unchecked Return Value to NULL Pointer Dereference.  */
     diagnostic_metadata m;
     m.add_cwe (690);
-    return warning_at (rich_loc, m, OPT_Wanalyzer_possible_null_dereference,
-		       "dereference of possibly-NULL %qE", m_arg);
+    return warning_with_metadata_at (rich_loc, m,
+				     OPT_Wanalyzer_possible_null_dereference,
+				     "dereference of possibly-NULL %qE", m_arg);
   }
 
   label_text describe_final_event (const evdesc::final_event &ev) FINAL OVERRIDE
@@ -296,10 +297,10 @@ public:
     auto_diagnostic_group d;
     diagnostic_metadata m;
     m.add_cwe (690);
-    bool warned
-      = warning_at (rich_loc, m, OPT_Wanalyzer_possible_null_argument,
-		    "use of possibly-NULL %qE where non-null expected",
-		    m_arg);
+    bool warned = warning_with_metadata_at
+      (rich_loc, m, OPT_Wanalyzer_possible_null_argument,
+       "use of possibly-NULL %qE where non-null expected",
+       m_arg);
     if (warned)
       inform_nonnull_attribute (m_fndecl, m_arg_idx);
     return warned;
@@ -338,8 +339,9 @@ public:
     /* CWE-690: Unchecked Return Value to NULL Pointer Dereference.  */
     diagnostic_metadata m;
     m.add_cwe (690);
-    return warning_at (rich_loc, m, OPT_Wanalyzer_null_dereference,
-		       "dereference of NULL %qE", m_arg);
+    return warning_with_metadata_at (rich_loc, m,
+				     OPT_Wanalyzer_null_dereference,
+				     "dereference of NULL %qE", m_arg);
   }
 
   label_text describe_return_of_state (const evdesc::return_of_state &info)
@@ -386,8 +388,11 @@ public:
     auto_diagnostic_group d;
     diagnostic_metadata m;
     m.add_cwe (690);
-    bool warned = warning_at (rich_loc, m, OPT_Wanalyzer_null_argument,
-			      "use of NULL %qE where non-null expected", m_arg);
+    bool warned
+      = warning_with_metadata_at (rich_loc,
+				  m, OPT_Wanalyzer_null_argument,
+				  "use of NULL %qE where non-null expected",
+				  m_arg);
     if (warned)
       inform_nonnull_attribute (m_fndecl, m_arg_idx);
     return warned;
@@ -419,8 +424,8 @@ public:
     /* CWE-416: Use After Free.  */
     diagnostic_metadata m;
     m.add_cwe (416);
-    return warning_at (rich_loc, m, OPT_Wanalyzer_use_after_free,
-		       "use after %<free%> of %qE", m_arg);
+    return warning_with_metadata_at (rich_loc, m, OPT_Wanalyzer_use_after_free,
+				     "use after %<free%> of %qE", m_arg);
   }
 
   label_text describe_state_change (const evdesc::state_change &change)
@@ -459,8 +464,8 @@ public:
   {
     diagnostic_metadata m;
     m.add_cwe (401);
-    return warning_at (rich_loc, m, OPT_Wanalyzer_malloc_leak,
-		       "leak of %qE", m_arg);
+    return warning_with_metadata_at (rich_loc, m, OPT_Wanalyzer_malloc_leak,
+				     "leak of %qE", m_arg);
   }
 
   label_text describe_state_change (const evdesc::state_change &change)
@@ -514,16 +519,17 @@ public:
       default:
 	gcc_unreachable ();
       case KIND_UNKNOWN:
-	return warning_at (rich_loc, m, OPT_Wanalyzer_free_of_non_heap,
-			   "%<free%> of %qE which points to memory"
-			   " not on the heap",
-			   m_arg);
+	return warning_with_metadata_at
+	  (rich_loc, m, OPT_Wanalyzer_free_of_non_heap,
+	   "%<free%> of %qE which points to memory not on the heap",
+	   m_arg);
 	break;
       case KIND_ALLOCA:
-	return warning_at (rich_loc, m, OPT_Wanalyzer_free_of_non_heap,
-			   "%<free%> of memory allocated on the stack by"
-			   " %qs (%qE) will corrupt the heap",
-			   "alloca", m_arg);
+	return warning_with_metadata_at
+	  (rich_loc, m, OPT_Wanalyzer_free_of_non_heap,
+	   "%<free%> of memory allocated on the stack by"
+	   " %qs (%qE) will corrupt the heap",
+	   "alloca", m_arg);
 	break;
       }
   }
diff --git a/gcc/analyzer/sm-sensitive.cc b/gcc/analyzer/sm-sensitive.cc
index a067c18fba4..04654a3ef62 100644
--- a/gcc/analyzer/sm-sensitive.cc
+++ b/gcc/analyzer/sm-sensitive.cc
@@ -105,9 +105,10 @@ public:
     diagnostic_metadata m;
     /* CWE-532: Information Exposure Through Log Files */
     m.add_cwe (532);
-    return warning_at (rich_loc, m, OPT_Wanalyzer_exposure_through_output_file,
-		       "sensitive value %qE written to output file",
-		       m_arg);
+    return warning_with_metadata_at
+      (rich_loc, m, OPT_Wanalyzer_exposure_through_output_file,
+       "sensitive value %qE written to output file",
+       m_arg);
   }
 
   label_text describe_state_change (const evdesc::state_change &change)
diff --git a/gcc/analyzer/sm-signal.cc b/gcc/analyzer/sm-signal.cc
index b4daf3ad617..3031993e869 100644
--- a/gcc/analyzer/sm-signal.cc
+++ b/gcc/analyzer/sm-signal.cc
@@ -126,10 +126,10 @@ public:
     diagnostic_metadata m;
     /* CWE-479: Signal Handler Use of a Non-reentrant Function.  */
     m.add_cwe (479);
-    return warning_at (rich_loc, m,
-		       OPT_Wanalyzer_unsafe_call_within_signal_handler,
-		       "call to %qD from within signal handler",
-		       m_unsafe_fndecl);
+    return warning_with_metadata_at
+      (rich_loc, m, OPT_Wanalyzer_unsafe_call_within_signal_handler,
+       "call to %qD from within signal handler",
+       m_unsafe_fndecl);
   }
 
   label_text describe_state_change (const evdesc::state_change &change)
diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc
index 00b794a3698..0ea2c764454 100644
--- a/gcc/analyzer/sm-taint.cc
+++ b/gcc/analyzer/sm-taint.cc
@@ -114,22 +114,25 @@ public:
       default:
 	gcc_unreachable ();
       case BOUNDS_NONE:
-	return warning_at (rich_loc, m, OPT_Wanalyzer_tainted_array_index,
-			   "use of tainted value %qE in array lookup"
-			   " without bounds checking",
-			   m_arg);
+	return warning_with_metadata_at
+	  (rich_loc, m, OPT_Wanalyzer_tainted_array_index,
+	   "use of tainted value %qE in array lookup"
+	   " without bounds checking",
+	   m_arg);
 	break;
       case BOUNDS_UPPER:
-	return warning_at (rich_loc, m, OPT_Wanalyzer_tainted_array_index,
-			   "use of tainted value %qE in array lookup"
-			   " without lower-bounds checking",
-			   m_arg);
+	return warning_with_metadata_at
+	  (rich_loc, m, OPT_Wanalyzer_tainted_array_index,
+	   "use of tainted value %qE in array lookup"
+	   " without lower-bounds checking",
+	   m_arg);
 	break;
       case BOUNDS_LOWER:
-	return warning_at (rich_loc, m, OPT_Wanalyzer_tainted_array_index,
-			   "use of tainted value %qE in array lookup"
-			   " without upper-bounds checking",
-			   m_arg);
+	return warning_with_metadata_at
+	  (rich_loc, m, OPT_Wanalyzer_tainted_array_index,
+	   "use of tainted value %qE in array lookup"
+	   " without upper-bounds checking",
+	   m_arg);
 	break;
       }
   }
diff --git a/gcc/diagnostic-core.h b/gcc/diagnostic-core.h
index 38b8557fd55..e322326531c 100644
--- a/gcc/diagnostic-core.h
+++ b/gcc/diagnostic-core.h
@@ -81,8 +81,9 @@ 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 bool warning_at (rich_location *, const diagnostic_metadata &, int,
-			const char *, ...)
+extern bool warning_with_metadata_at (rich_location *,
+				      const diagnostic_metadata &, int,
+				      const char *, ...)
     ATTRIBUTE_GCC_DIAG(4,5);
 extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
 extern void error_n (location_t, unsigned HOST_WIDE_INT, const char *,
@@ -115,10 +116,6 @@ extern bool emit_diagnostic (diagnostic_t, rich_location *, int,
 			     const char *, ...) ATTRIBUTE_GCC_DIAG(4,5);
 extern bool emit_diagnostic_valist (diagnostic_t, location_t, int, const char *,
 				    va_list *) ATTRIBUTE_GCC_DIAG (4,0);
-extern bool emit_diagnostic_valist (diagnostic_t, rich_location *,
-				    const diagnostic_metadata *metadata,
-				    int, const char *, va_list *)
-  ATTRIBUTE_GCC_DIAG (5,0);
 extern bool seen_error (void);
 
 #ifdef BUFSIZ
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 72afd7c6adf..4a599e4c380 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -1356,17 +1356,6 @@ emit_diagnostic_valist (diagnostic_t kind, location_t location, int opt,
   return diagnostic_impl (&richloc, NULL, opt, gmsgid, ap, kind);
 }
 
-/* Wrapper around diagnostic_impl taking a va_list parameter.  */
-
-bool
-emit_diagnostic_valist (diagnostic_t kind, rich_location *richloc,
-			const diagnostic_metadata *metadata,
-			int opt,
-			const char *gmsgid, va_list *ap)
-{
-  return diagnostic_impl (richloc, metadata, opt, gmsgid, ap, kind);
-}
-
 /* An informative note at LOCATION.  Use this for additional details on an error
    message.  */
 void
@@ -1457,8 +1446,9 @@ warning_at (rich_location *richloc, int opt, const char *gmsgid, ...)
 /* Same as "warning at" above, but using METADATA.  */
 
 bool
-warning_at (rich_location *richloc, const diagnostic_metadata &metadata,
-	    int opt, const char *gmsgid, ...)
+warning_with_metadata_at (rich_location *richloc,
+			  const diagnostic_metadata &metadata,
+			  int opt, const char *gmsgid, ...)
 {
   gcc_assert (richloc);
 
-- 
2.21.0

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] diagnostic_metadata: unbreak xgettext
  2020-01-28 14:46   ` [PATCH] diagnostic_metadata: unbreak xgettext David Malcolm
@ 2020-01-28 14:56     ` Jakub Jelinek
  2020-01-28 15:42       ` [PATCH] diagnostic_metadata: unbreak xgettext (v2) David Malcolm
  0 siblings, 1 reply; 7+ messages in thread
From: Jakub Jelinek @ 2020-01-28 14:56 UTC (permalink / raw)
  To: David Malcolm; +Cc: Joseph S . Myers, gcc-patches

On Tue, Jan 28, 2020 at 09:30:17AM -0500, David Malcolm wrote:
> 	* diagnostic-core.h (warning_at): Rename overload to...
> 	(warning_with_metadata_at): ...this.

I think this is just too long, especially for a function used at least
in the analyzer pretty often, leading to lots of ugly formatting.
Can't you use warning_meta or something similar instead?

> 	(emit_diagnostic_valist): Delete decl of overload taking
> 	diagnostic_metadata.
> 	* diagnostic.c (emit_diagnostic_valist): Likewise for defn.
> 	(warning_at): Rename overload taking diagnostic_metadata to...
> 	(warning_with_metadata_at): ...this.

	Jakub

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] diagnostic_metadata: unbreak xgettext (v2)
  2020-01-28 14:56     ` Jakub Jelinek
@ 2020-01-28 15:42       ` David Malcolm
  2020-01-28 16:05         ` Jakub Jelinek
  0 siblings, 1 reply; 7+ messages in thread
From: David Malcolm @ 2020-01-28 15:42 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Joseph S . Myers, gcc-patches, David Malcolm

On Tue, 2020-01-28 at 15:36 +0100, Jakub Jelinek wrote:
> On Tue, Jan 28, 2020 at 09:30:17AM -0500, David Malcolm wrote:
> > 	* diagnostic-core.h (warning_at): Rename overload to...
> > 	(warning_with_metadata_at): ...this.
> 
> I think this is just too long, especially for a function used at
> least
> in the analyzer pretty often, leading to lots of ugly formatting.
> Can't you use warning_meta or something similar instead?
> 
> > 	(emit_diagnostic_valist): Delete decl of overload taking
> > 	diagnostic_metadata.
> > 	* diagnostic.c (emit_diagnostic_valist): Likewise for defn.
> > 	(warning_at): Rename overload taking diagnostic_metadata to...
> > 	(warning_with_metadata_at): ...this.
> 
> 	Jakub

Fair enough, thanks.  Bootstrap in progress of v2:

Changed in v2:
- rename from warning_with_metadata_at to warning_meta
- fix test plugins

While C++ can have overloads, xgettext can't deal with overloads that have
different argument positions, leading to two failures in "make gcc.pot":

emit_diagnostic_valist used incompatibly as both
--keyword=emit_diagnostic_valist:4
--flag=emit_diagnostic_valist:4:gcc-internal-format and
--keyword=emit_diagnostic_valist:5
--flag=emit_diagnostic_valist:5:gcc-internal-format

warning_at used incompatibly as both
--keyword=warning_at:3 --flag=warning_at:3:gcc-internal-format and
--keyword=warning_at:4 --flag=warning_at:4:gcc-internal-format

The emit_diagnostic_valist overload isn't used anywhere (I think it's
a leftover from an earlier iteration of the analyzer patch kit).

The warning_at overload is used throughout the analyzer but nowhere else.

Ideally I'd like to consolidate this argument with something
constructable in various ways:
- from a metadata and an int or
- from an int (or, better an "enum opt_code"),
so that the overload happens when implicitly choosing the ctor, but
that feels like stage 1 material.

In the meantime, fix xgettext by deleting the unused overload and
renaming the used one.

gcc/analyzer/ChangeLog:
	* region-model.cc (poisoned_value_diagnostic::emit): Update for
	renaming of warning_at overload to warning_meta.
	* sm-file.cc (file_leak::emit): Likewise.
	* sm-malloc.cc (double_free::emit): Likewise.
	(possible_null_deref::emit): Likewise.
	(possible_null_arg::emit): Likewise.
	(null_deref::emit): Likewise.
	(null_arg::emit): Likewise.
	(use_after_free::emit): Likewise.
	(malloc_leak::emit): Likewise.
	(free_of_non_heap::emit): Likewise.
	* sm-sensitive.cc (exposure_through_output_file::emit): Likewise.
	* sm-signal.cc (signal_unsafe_call::emit): Likewise.
	* sm-taint.cc (tainted_array_index::emit): Likewise.

gcc/ChangeLog:
	* diagnostic-core.h (warning_at): Rename overload to...
	(warning_meta): ...this.
	(emit_diagnostic_valist): Delete decl of overload taking
	diagnostic_metadata.
	* diagnostic.c (emit_diagnostic_valist): Likewise for defn.
	(warning_at): Rename overload taking diagnostic_metadata to...
	(warning_meta): ...this.

gcc/testsuite/ChangeLog:
	* gcc.dg/plugin/diagnostic_plugin_test_metadata.c: Update for
	renaming of warning_at overload to warning_meta.
	* gcc.dg/plugin/diagnostic_plugin_test_paths.c: Likewise.
---
 gcc/analyzer/region-model.cc                  | 19 ++++---
 gcc/analyzer/sm-file.cc                       |  6 +--
 gcc/analyzer/sm-malloc.cc                     | 49 ++++++++++---------
 gcc/analyzer/sm-sensitive.cc                  |  7 +--
 gcc/analyzer/sm-signal.cc                     |  8 +--
 gcc/analyzer/sm-taint.cc                      | 24 ++++-----
 gcc/diagnostic-core.h                         |  9 ++--
 gcc/diagnostic.c                              | 16 ++----
 .../plugin/diagnostic_plugin_test_metadata.c  |  4 +-
 .../plugin/diagnostic_plugin_test_paths.c     | 13 ++---
 10 files changed, 73 insertions(+), 82 deletions(-)

diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 62c96a6ceea..acaadcf9d3b 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -3827,27 +3827,26 @@ public:
 	{
 	  diagnostic_metadata m;
 	  m.add_cwe (457); /* "CWE-457: Use of Uninitialized Variable".  */
-	  return warning_at (rich_loc, m,
-			     OPT_Wanalyzer_use_of_uninitialized_value,
-			     "use of uninitialized value %qE",
-			     m_expr);
+	  return warning_meta (rich_loc, m,
+			       OPT_Wanalyzer_use_of_uninitialized_value,
+			       "use of uninitialized value %qE",
+			       m_expr);
 	}
 	break;
       case POISON_KIND_FREED:
 	{
 	  diagnostic_metadata m;
 	  m.add_cwe (416); /* "CWE-416: Use After Free".  */
-	  return warning_at (rich_loc, m,
-			     OPT_Wanalyzer_use_after_free,
-			     "use after %<free%> of %qE",
-			     m_expr);
+	  return warning_meta (rich_loc, m,
+			       OPT_Wanalyzer_use_after_free,
+			       "use after %<free%> of %qE",
+			       m_expr);
 	}
 	break;
       case POISON_KIND_POPPED_STACK:
 	{
-	  diagnostic_metadata m;
 	  /* TODO: which CWE?  */
-	  return warning_at (rich_loc, m,
+	  return warning_at (rich_loc,
 			     OPT_Wanalyzer_use_of_pointer_in_stale_stack_frame,
 			     "use of pointer %qE within stale stack frame",
 			     m_expr);
diff --git a/gcc/analyzer/sm-file.cc b/gcc/analyzer/sm-file.cc
index 11444926538..7c546997a0c 100644
--- a/gcc/analyzer/sm-file.cc
+++ b/gcc/analyzer/sm-file.cc
@@ -178,9 +178,9 @@ public:
     /* CWE-775: "Missing Release of File Descriptor or Handle after
        Effective Lifetime". */
     m.add_cwe (775);
-    return warning_at (rich_loc, m, OPT_Wanalyzer_file_leak,
-		       "leak of FILE %qE",
-		       m_arg);
+    return warning_meta (rich_loc, m, OPT_Wanalyzer_file_leak,
+			 "leak of FILE %qE",
+			 m_arg);
   }
 
   label_text describe_state_change (const evdesc::state_change &change)
diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc
index 526680accf2..9415a074135 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -145,8 +145,8 @@ public:
     auto_diagnostic_group d;
     diagnostic_metadata m;
     m.add_cwe (415); /* CWE-415: Double Free.  */
-    return warning_at (rich_loc, m, OPT_Wanalyzer_double_free,
-		       "double-%<free%> of %qE", m_arg);
+    return warning_meta (rich_loc, m, OPT_Wanalyzer_double_free,
+			 "double-%<free%> of %qE", m_arg);
   }
 
   label_text describe_state_change (const evdesc::state_change &change)
@@ -235,8 +235,9 @@ public:
     /* CWE-690: Unchecked Return Value to NULL Pointer Dereference.  */
     diagnostic_metadata m;
     m.add_cwe (690);
-    return warning_at (rich_loc, m, OPT_Wanalyzer_possible_null_dereference,
-		       "dereference of possibly-NULL %qE", m_arg);
+    return warning_meta (rich_loc, m,
+			 OPT_Wanalyzer_possible_null_dereference,
+			 "dereference of possibly-NULL %qE", m_arg);
   }
 
   label_text describe_final_event (const evdesc::final_event &ev) FINAL OVERRIDE
@@ -297,9 +298,9 @@ public:
     diagnostic_metadata m;
     m.add_cwe (690);
     bool warned
-      = warning_at (rich_loc, m, OPT_Wanalyzer_possible_null_argument,
-		    "use of possibly-NULL %qE where non-null expected",
-		    m_arg);
+      = warning_meta (rich_loc, m, OPT_Wanalyzer_possible_null_argument,
+		      "use of possibly-NULL %qE where non-null expected",
+		      m_arg);
     if (warned)
       inform_nonnull_attribute (m_fndecl, m_arg_idx);
     return warned;
@@ -338,8 +339,9 @@ public:
     /* CWE-690: Unchecked Return Value to NULL Pointer Dereference.  */
     diagnostic_metadata m;
     m.add_cwe (690);
-    return warning_at (rich_loc, m, OPT_Wanalyzer_null_dereference,
-		       "dereference of NULL %qE", m_arg);
+    return warning_meta (rich_loc, m,
+			 OPT_Wanalyzer_null_dereference,
+			 "dereference of NULL %qE", m_arg);
   }
 
   label_text describe_return_of_state (const evdesc::return_of_state &info)
@@ -386,8 +388,9 @@ public:
     auto_diagnostic_group d;
     diagnostic_metadata m;
     m.add_cwe (690);
-    bool warned = warning_at (rich_loc, m, OPT_Wanalyzer_null_argument,
-			      "use of NULL %qE where non-null expected", m_arg);
+    bool warned = warning_meta (rich_loc, m, OPT_Wanalyzer_null_argument,
+				"use of NULL %qE where non-null expected",
+				m_arg);
     if (warned)
       inform_nonnull_attribute (m_fndecl, m_arg_idx);
     return warned;
@@ -419,8 +422,8 @@ public:
     /* CWE-416: Use After Free.  */
     diagnostic_metadata m;
     m.add_cwe (416);
-    return warning_at (rich_loc, m, OPT_Wanalyzer_use_after_free,
-		       "use after %<free%> of %qE", m_arg);
+    return warning_meta (rich_loc, m, OPT_Wanalyzer_use_after_free,
+			 "use after %<free%> of %qE", m_arg);
   }
 
   label_text describe_state_change (const evdesc::state_change &change)
@@ -459,8 +462,8 @@ public:
   {
     diagnostic_metadata m;
     m.add_cwe (401);
-    return warning_at (rich_loc, m, OPT_Wanalyzer_malloc_leak,
-		       "leak of %qE", m_arg);
+    return warning_meta (rich_loc, m, OPT_Wanalyzer_malloc_leak,
+			 "leak of %qE", m_arg);
   }
 
   label_text describe_state_change (const evdesc::state_change &change)
@@ -514,16 +517,16 @@ public:
       default:
 	gcc_unreachable ();
       case KIND_UNKNOWN:
-	return warning_at (rich_loc, m, OPT_Wanalyzer_free_of_non_heap,
-			   "%<free%> of %qE which points to memory"
-			   " not on the heap",
-			   m_arg);
+	return warning_meta (rich_loc, m, OPT_Wanalyzer_free_of_non_heap,
+			     "%<free%> of %qE which points to memory"
+			     " not on the heap",
+			     m_arg);
 	break;
       case KIND_ALLOCA:
-	return warning_at (rich_loc, m, OPT_Wanalyzer_free_of_non_heap,
-			   "%<free%> of memory allocated on the stack by"
-			   " %qs (%qE) will corrupt the heap",
-			   "alloca", m_arg);
+	return warning_meta (rich_loc, m, OPT_Wanalyzer_free_of_non_heap,
+			     "%<free%> of memory allocated on the stack by"
+			     " %qs (%qE) will corrupt the heap",
+			     "alloca", m_arg);
 	break;
       }
   }
diff --git a/gcc/analyzer/sm-sensitive.cc b/gcc/analyzer/sm-sensitive.cc
index a067c18fba4..ff0c3284843 100644
--- a/gcc/analyzer/sm-sensitive.cc
+++ b/gcc/analyzer/sm-sensitive.cc
@@ -105,9 +105,10 @@ public:
     diagnostic_metadata m;
     /* CWE-532: Information Exposure Through Log Files */
     m.add_cwe (532);
-    return warning_at (rich_loc, m, OPT_Wanalyzer_exposure_through_output_file,
-		       "sensitive value %qE written to output file",
-		       m_arg);
+    return warning_meta (rich_loc, m,
+			 OPT_Wanalyzer_exposure_through_output_file,
+			 "sensitive value %qE written to output file",
+			 m_arg);
   }
 
   label_text describe_state_change (const evdesc::state_change &change)
diff --git a/gcc/analyzer/sm-signal.cc b/gcc/analyzer/sm-signal.cc
index b4daf3ad617..247e0ec750c 100644
--- a/gcc/analyzer/sm-signal.cc
+++ b/gcc/analyzer/sm-signal.cc
@@ -126,10 +126,10 @@ public:
     diagnostic_metadata m;
     /* CWE-479: Signal Handler Use of a Non-reentrant Function.  */
     m.add_cwe (479);
-    return warning_at (rich_loc, m,
-		       OPT_Wanalyzer_unsafe_call_within_signal_handler,
-		       "call to %qD from within signal handler",
-		       m_unsafe_fndecl);
+    return warning_meta (rich_loc, m,
+			 OPT_Wanalyzer_unsafe_call_within_signal_handler,
+			 "call to %qD from within signal handler",
+			 m_unsafe_fndecl);
   }
 
   label_text describe_state_change (const evdesc::state_change &change)
diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc
index 00b794a3698..dff43a4ea80 100644
--- a/gcc/analyzer/sm-taint.cc
+++ b/gcc/analyzer/sm-taint.cc
@@ -114,22 +114,22 @@ public:
       default:
 	gcc_unreachable ();
       case BOUNDS_NONE:
-	return warning_at (rich_loc, m, OPT_Wanalyzer_tainted_array_index,
-			   "use of tainted value %qE in array lookup"
-			   " without bounds checking",
-			   m_arg);
+	return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_array_index,
+			     "use of tainted value %qE in array lookup"
+			     " without bounds checking",
+			     m_arg);
 	break;
       case BOUNDS_UPPER:
-	return warning_at (rich_loc, m, OPT_Wanalyzer_tainted_array_index,
-			   "use of tainted value %qE in array lookup"
-			   " without lower-bounds checking",
-			   m_arg);
+	return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_array_index,
+			     "use of tainted value %qE in array lookup"
+			     " without lower-bounds checking",
+			     m_arg);
 	break;
       case BOUNDS_LOWER:
-	return warning_at (rich_loc, m, OPT_Wanalyzer_tainted_array_index,
-			   "use of tainted value %qE in array lookup"
-			   " without upper-bounds checking",
-			   m_arg);
+	return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_array_index,
+			     "use of tainted value %qE in array lookup"
+			     " without upper-bounds checking",
+			     m_arg);
 	break;
       }
   }
diff --git a/gcc/diagnostic-core.h b/gcc/diagnostic-core.h
index 38b8557fd55..a18d2e3206e 100644
--- a/gcc/diagnostic-core.h
+++ b/gcc/diagnostic-core.h
@@ -81,8 +81,9 @@ 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 bool warning_at (rich_location *, const diagnostic_metadata &, int,
-			const char *, ...)
+extern bool warning_meta (rich_location *,
+			  const diagnostic_metadata &, int,
+			  const char *, ...)
     ATTRIBUTE_GCC_DIAG(4,5);
 extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
 extern void error_n (location_t, unsigned HOST_WIDE_INT, const char *,
@@ -115,10 +116,6 @@ extern bool emit_diagnostic (diagnostic_t, rich_location *, int,
 			     const char *, ...) ATTRIBUTE_GCC_DIAG(4,5);
 extern bool emit_diagnostic_valist (diagnostic_t, location_t, int, const char *,
 				    va_list *) ATTRIBUTE_GCC_DIAG (4,0);
-extern bool emit_diagnostic_valist (diagnostic_t, rich_location *,
-				    const diagnostic_metadata *metadata,
-				    int, const char *, va_list *)
-  ATTRIBUTE_GCC_DIAG (5,0);
 extern bool seen_error (void);
 
 #ifdef BUFSIZ
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 72afd7c6adf..3386f070256 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -1356,17 +1356,6 @@ emit_diagnostic_valist (diagnostic_t kind, location_t location, int opt,
   return diagnostic_impl (&richloc, NULL, opt, gmsgid, ap, kind);
 }
 
-/* Wrapper around diagnostic_impl taking a va_list parameter.  */
-
-bool
-emit_diagnostic_valist (diagnostic_t kind, rich_location *richloc,
-			const diagnostic_metadata *metadata,
-			int opt,
-			const char *gmsgid, va_list *ap)
-{
-  return diagnostic_impl (richloc, metadata, opt, gmsgid, ap, kind);
-}
-
 /* An informative note at LOCATION.  Use this for additional details on an error
    message.  */
 void
@@ -1457,8 +1446,9 @@ warning_at (rich_location *richloc, int opt, const char *gmsgid, ...)
 /* Same as "warning at" above, but using METADATA.  */
 
 bool
-warning_at (rich_location *richloc, const diagnostic_metadata &metadata,
-	    int opt, const char *gmsgid, ...)
+warning_meta (rich_location *richloc,
+	      const diagnostic_metadata &metadata,
+	      int opt, const char *gmsgid, ...)
 {
   gcc_assert (richloc);
 
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.c
index 5e58115afba..a6108919b24 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.c
@@ -109,8 +109,8 @@ pass_test_metadata::execute (function *fun)
 	    /* CWE-242: Use of Inherently Dangerous Function.  */
 	    diagnostic_metadata m;
 	    m.add_cwe (242);
-	    warning_at (&richloc, m, 0,
-			"never use %qs", "gets");
+	    warning_meta (&richloc, m, 0,
+			  "never use %qs", "gets");
 	  }
       }
 
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c
index cf05ca3a5d3..76728757290 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c
@@ -328,7 +328,8 @@ example_2 ()
 			 entry_to_wrapped_free, "wrapped_free");
 	  path.add_leaf_call (call_to_free, 2, "free");
 	  if (i == 0 && call_to_missing_location.m_fun)
-	    path.add_leaf_call (call_to_missing_location, 0, "missing_location");
+	    path.add_leaf_call (call_to_missing_location, 0,
+				"missing_location");
 	}
 
       richloc.set_path (&path);
@@ -336,8 +337,8 @@ example_2 ()
       diagnostic_metadata m;
       m.add_cwe (415); /* CWE-415: Double Free.  */
 
-      warning_at (&richloc, m, 0,
-		  "double-free of %qs", "ptr");
+      warning_meta (&richloc, m, 0,
+		    "double-free of %qs", "ptr");
     }
 }
 
@@ -415,9 +416,9 @@ example_3 ()
       /* CWE-479: Signal Handler Use of a Non-reentrant Function.  */
       m.add_cwe (479);
 
-      warning_at (&richloc, m, 0,
-		  "call to %qs from within signal handler",
-		  "fprintf");
+      warning_meta (&richloc, m, 0,
+		    "call to %qs from within signal handler",
+		    "fprintf");
     }
 }
 
-- 
2.21.0

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] diagnostic_metadata: unbreak xgettext (v2)
  2020-01-28 15:42       ` [PATCH] diagnostic_metadata: unbreak xgettext (v2) David Malcolm
@ 2020-01-28 16:05         ` Jakub Jelinek
  2020-01-28 19:40           ` David Malcolm
  0 siblings, 1 reply; 7+ messages in thread
From: Jakub Jelinek @ 2020-01-28 16:05 UTC (permalink / raw)
  To: David Malcolm; +Cc: Joseph S . Myers, gcc-patches

On Tue, Jan 28, 2020 at 10:30:58AM -0500, David Malcolm wrote:
> gcc/analyzer/ChangeLog:
> 	* region-model.cc (poisoned_value_diagnostic::emit): Update for
> 	renaming of warning_at overload to warning_meta.
> 	* sm-file.cc (file_leak::emit): Likewise.
> 	* sm-malloc.cc (double_free::emit): Likewise.
> 	(possible_null_deref::emit): Likewise.
> 	(possible_null_arg::emit): Likewise.
> 	(null_deref::emit): Likewise.
> 	(null_arg::emit): Likewise.
> 	(use_after_free::emit): Likewise.
> 	(malloc_leak::emit): Likewise.
> 	(free_of_non_heap::emit): Likewise.
> 	* sm-sensitive.cc (exposure_through_output_file::emit): Likewise.
> 	* sm-signal.cc (signal_unsafe_call::emit): Likewise.
> 	* sm-taint.cc (tainted_array_index::emit): Likewise.
> 
> gcc/ChangeLog:
> 	* diagnostic-core.h (warning_at): Rename overload to...
> 	(warning_meta): ...this.
> 	(emit_diagnostic_valist): Delete decl of overload taking
> 	diagnostic_metadata.
> 	* diagnostic.c (emit_diagnostic_valist): Likewise for defn.
> 	(warning_at): Rename overload taking diagnostic_metadata to...
> 	(warning_meta): ...this.
> 
> gcc/testsuite/ChangeLog:
> 	* gcc.dg/plugin/diagnostic_plugin_test_metadata.c: Update for
> 	renaming of warning_at overload to warning_meta.
> 	* gcc.dg/plugin/diagnostic_plugin_test_paths.c: Likewise.

LGTM, thanks.

	Jakub

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] diagnostic_metadata: unbreak xgettext (v2)
  2020-01-28 16:05         ` Jakub Jelinek
@ 2020-01-28 19:40           ` David Malcolm
  0 siblings, 0 replies; 7+ messages in thread
From: David Malcolm @ 2020-01-28 19:40 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Joseph S . Myers, gcc-patches

On Tue, 2020-01-28 at 16:34 +0100, Jakub Jelinek wrote:
> On Tue, Jan 28, 2020 at 10:30:58AM -0500, David Malcolm wrote:
> > gcc/analyzer/ChangeLog:
> > 	* region-model.cc (poisoned_value_diagnostic::emit): Update for
> > 	renaming of warning_at overload to warning_meta.
> > 	* sm-file.cc (file_leak::emit): Likewise.
> > 	* sm-malloc.cc (double_free::emit): Likewise.
> > 	(possible_null_deref::emit): Likewise.
> > 	(possible_null_arg::emit): Likewise.
> > 	(null_deref::emit): Likewise.
> > 	(null_arg::emit): Likewise.
> > 	(use_after_free::emit): Likewise.
> > 	(malloc_leak::emit): Likewise.
> > 	(free_of_non_heap::emit): Likewise.
> > 	* sm-sensitive.cc (exposure_through_output_file::emit):
> > Likewise.
> > 	* sm-signal.cc (signal_unsafe_call::emit): Likewise.
> > 	* sm-taint.cc (tainted_array_index::emit): Likewise.
> > 
> > gcc/ChangeLog:
> > 	* diagnostic-core.h (warning_at): Rename overload to...
> > 	(warning_meta): ...this.
> > 	(emit_diagnostic_valist): Delete decl of overload taking
> > 	diagnostic_metadata.
> > 	* diagnostic.c (emit_diagnostic_valist): Likewise for defn.
> > 	(warning_at): Rename overload taking diagnostic_metadata to...
> > 	(warning_meta): ...this.
> > 
> > gcc/testsuite/ChangeLog:
> > 	* gcc.dg/plugin/diagnostic_plugin_test_metadata.c: Update for
> > 	renaming of warning_at overload to warning_meta.
> > 	* gcc.dg/plugin/diagnostic_plugin_test_paths.c: Likewise.
> 
> LGTM, thanks

Thanks.   B&R succeeded, so pushed to master
(6c8e584430bc5dc01b4438f3c38a2a10fcba7685).

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-01-28 18:49 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-19  0:10 [committed] Add diagnostic_metadata and CWE support David Malcolm
2020-01-28 10:40 ` Jakub Jelinek
2020-01-28 14:46   ` [PATCH] diagnostic_metadata: unbreak xgettext David Malcolm
2020-01-28 14:56     ` Jakub Jelinek
2020-01-28 15:42       ` [PATCH] diagnostic_metadata: unbreak xgettext (v2) David Malcolm
2020-01-28 16:05         ` Jakub Jelinek
2020-01-28 19:40           ` David Malcolm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).