This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 09/45] Add diagnostic_metadata and CWE support
- From: David Malcolm <dmalcolm at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: David Malcolm <dmalcolm at redhat dot com>
- Date: Fri, 13 Dec 2019 13:10:58 -0500
- Subject: [PATCH 09/45] Add diagnostic_metadata and CWE support
- References: <20191213181134.1830-1-dmalcolm@redhat.com>
Changed in v2:
fixup for json::number -> json::integer_number change (r277284)
https://gcc.gnu.org/ml/gcc-patches/2019-11/msg02027.html
This patch adds support for associating a diagnostic 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 analyzer warnings later in
the 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.
gcc/ChangeLog:
* common.opt (fdiagnostics-show-metadata): New option.
* 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_metadata.
* 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_metadata.
(diagnostic_set_info_translated): Initialize diagnostic->metadata.
(get_cwe_url): New function.
(print_any_metadata): New function.
(diagnostic_report_diagnostic): Call print_any_metadata 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_metadata): New field.
* doc/invoke.texi (-fno-diagnostics-show-metadata): New option.
* opts.c (common_handle_option): Handle
OPT_fdiagnostics_show_metadata.
* toplev.c (general_init): Initialize global_dc->show_metadata.
---
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 | 7 ++
gcc/doc/invoke.texi | 8 ++
gcc/opts.c | 4 +
gcc/toplev.c | 2 +
9 files changed, 212 insertions(+), 31 deletions(-)
create mode 100644 gcc/diagnostic-metadata.h
diff --git a/gcc/common.opt b/gcc/common.opt
index d5727c300c07..0bde11b74917 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1338,6 +1338,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-metadata
+Common Var(flag_diagnostics_show_metadata) Init(1)
+Print additional metadata 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 efafde4fa24a..2e7f12070fbd 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 6782ec9dffb0..cddecb2d463a 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_metadata = 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 000000000000..a759d44fa440
--- /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 81e0a100169b..e8d0613cde41 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_metadata = false;
context->show_option_requested = false;
context->abort_on_error = false;
context->show_column = false;
@@ -300,6 +304,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;
}
@@ -899,6 +904,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 metadata, 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_metadata (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. */
@@ -1059,6 +1105,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_metadata)
+ print_any_metadata (context, diagnostic);
if (context->show_option_requested)
print_option_information (context, diagnostic, orig_diag_kind);
(*diagnostic_finalizer (context)) (context, diagnostic, orig_diag_kind);
@@ -1190,8 +1238,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;
@@ -1207,13 +1255,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)
@@ -1233,6 +1283,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);
}
@@ -1246,7 +1297,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;
}
@@ -1260,7 +1311,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;
}
@@ -1272,7 +1323,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
@@ -1284,7 +1346,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);
}
@@ -1297,7 +1359,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);
}
@@ -1311,7 +1373,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);
}
@@ -1326,7 +1388,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;
}
@@ -1342,7 +1404,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;
}
@@ -1357,7 +1419,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;
}
@@ -1373,7 +1453,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);
@@ -1392,7 +1472,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);
@@ -1419,7 +1499,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;
}
@@ -1434,7 +1514,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;
}
@@ -1453,7 +1533,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;
}
@@ -1468,7 +1548,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;
}
@@ -1482,7 +1562,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);
}
@@ -1496,7 +1576,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);
}
@@ -1509,7 +1589,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);
}
@@ -1523,7 +1603,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);
}
@@ -1537,7 +1617,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);
}
@@ -1549,7 +1629,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);
}
@@ -1571,7 +1651,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 ();
@@ -1588,7 +1668,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 ();
@@ -1604,7 +1684,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 2fb75e6ffca6..0e4b6ad389de 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,9 @@ struct diagnostic_context
/* Character used for caret diagnostics. */
char caret_chars[rich_location::STATICALLY_ALLOCATED_RANGES];
+ /* True if we should print any metadata associated with diagnostics. */
+ bool show_metadata;
+
/* 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 6e8552de73f2..51e61c241703 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -279,6 +279,7 @@ Objective-C and Objective-C++ Dialects}.
-fno-diagnostics-show-option -fno-diagnostics-show-caret @gol
-fno-diagnostics-show-labels -fno-diagnostics-show-line-numbers @gol
-fdiagnostics-nn-line-numbers @gol
+-fno-diagnostics-show-metadata @gol
-fdiagnostics-minimum-margin-width=@var{width} @gol
-fdiagnostics-parseable-fixits -fdiagnostics-generate-patch @gol
-fdiagnostics-show-template-tree -fno-elide-type @gol
@@ -4022,6 +4023,13 @@ 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-metadata
+@opindex fno-diagnostics-show-metadata
+@opindex fdiagnostics-show-metadata
+Diagnostics can optionally contain @url{https://cwe.mitre.org/index.html, CWE}
+metadata. 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 de7887274938..0f2cf1910280 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -2411,6 +2411,10 @@ common_handle_option (struct gcc_options *opts,
dc->parseable_fixits_p = value;
break;
+ case OPT_fdiagnostics_show_metadata:
+ dc->show_metadata = value;
+ break;
+
case OPT_fdiagnostics_show_option:
dc->show_option_requested = value;
break;
diff --git a/gcc/toplev.c b/gcc/toplev.c
index b5fba7762e34..e94ffd0b5800 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1181,6 +1181,8 @@ general_init (const char *argv0, bool init_signals)
= global_options_init.x_flag_diagnostics_show_line_numbers;
global_dc->use_nn_for_line_numbers_p
= global_options_init.x_flag_diagnostics_nn_line_numbers;
+ global_dc->show_metadata
+ = global_options_init.x_flag_diagnostics_show_metadata;
global_dc->show_option_requested
= global_options_init.x_flag_diagnostics_show_option;
global_dc->min_margin_width
--
2.21.0