Common Var(flag_diagnostics_show_cwe) Init(1)
Print CWE identifiers for diagnostic messages, where available.
+fdiagnostics-show-rules
+Common Var(flag_diagnostics_show_rules) Init(1)
+Print any rules associated with diagnostic messages.
+
fdiagnostics-path-format=
Common Joined RejectNegative Var(flag_diagnostics_path_format) Enum(diagnostic_path_format) Init(DPF_INLINE_EVENTS)
Specify how to print any control-flow path associated with a diagnostic.
/* The metadata is handled in JSON format, rather than as text. */
context->show_cwe = false;
+ context->show_rules = false;
/* The option is handled in JSON format, rather than as text. */
context->show_option_requested = false;
/* The metadata is handled in SARIF format, rather than as text. */
context->show_cwe = false;
+ context->show_rules = false;
/* The option is handled in SARIF format, rather than as text. */
context->show_option_requested = false;
/* A bundle of additional metadata that can be associated with a
diagnostic.
- Currently this only supports associating a CWE identifier with a
- diagnostic. */
+ This supports an optional CWE identifier, and zero or more
+ "rules". */
class diagnostic_metadata
{
public:
+ /* Abstract base class for referencing a rule that has been violated,
+ such as within a coding standard, or within a specification. */
+ class rule
+ {
+ public:
+ virtual char *make_description () const = 0;
+ virtual char *make_url () const = 0;
+ };
+
+ /* Concrete subclass. */
+ class precanned_rule : public rule
+ {
+ public:
+ precanned_rule (const char *desc, const char *url)
+ : m_desc (desc), m_url (url)
+ {}
+
+ char *make_description () const final override
+ {
+ return m_desc ? xstrdup (m_desc) : NULL;
+ }
+
+ char *make_url () const final override
+ {
+ return m_url ? xstrdup (m_url) : NULL;
+ }
+
+ private:
+ const char *m_desc;
+ const char *m_url;
+ };
+
diagnostic_metadata () : m_cwe (0) {}
void add_cwe (int cwe) { m_cwe = cwe; }
int get_cwe () const { return m_cwe; }
+ /* Associate R with the diagnostic. R must outlive
+ the metadata. */
+ void add_rule (const rule &r)
+ {
+ m_rules.safe_push (&r);
+ }
+
+ unsigned get_num_rules () const { return m_rules.length (); }
+ const rule &get_rule (unsigned idx) const { return *(m_rules[idx]); }
+
private:
int m_cwe;
+ auto_vec<const rule *> m_rules;
};
#endif /* ! GCC_DIAGNOSTIC_METADATA_H */
for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++)
context->caret_chars[i] = '^';
context->show_cwe = false;
+ context->show_rules = false;
context->path_format = DPF_NONE;
context->show_path_depths = false;
context->show_option_requested = false;
}
}
+/* If DIAGNOSTIC has any rules associated with it, print them.
+
+ For example, if the diagnostic metadata associates it with a rule
+ named "STR34-C", then " [STR34-C]" will be printed, suitably colorized,
+ with any URL provided by the rule. */
+
+static void
+print_any_rules (diagnostic_context *context,
+ const diagnostic_info *diagnostic)
+{
+ if (diagnostic->metadata == NULL)
+ return;
+
+ for (unsigned idx = 0; idx < diagnostic->metadata->get_num_rules (); idx++)
+ {
+ const diagnostic_metadata::rule &rule
+ = diagnostic->metadata->get_rule (idx);
+ if (char *desc = rule.make_description ())
+ {
+ 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 *url = NULL;
+ if (pp->url_format != URL_FORMAT_NONE)
+ {
+ url = rule.make_url ();
+ if (url)
+ pp_begin_url (pp, url);
+ }
+ pp_string (pp, desc);
+ pp_set_prefix (context->printer, saved_prefix);
+ if (pp->url_format != URL_FORMAT_NONE)
+ if (url)
+ pp_end_url (pp);
+ free (url);
+ pp_string (pp, colorize_stop (pp_show_color (pp)));
+ pp_character (pp, ']');
+ free (desc);
+ }
+ }
+}
+
/* Print any metadata about the option used to control DIAGNOSTIC to CONTEXT's
printer, e.g. " [-Werror=uninitialized]".
Subroutine of diagnostic_report_diagnostic. */
pp_output_formatted_text (context->printer);
if (context->show_cwe)
print_any_cwe (context, diagnostic);
+ if (context->show_rules)
+ print_any_rules (context, diagnostic);
if (context->show_option_requested)
print_option_information (context, diagnostic, orig_diag_kind);
(*diagnostic_finalizer (context)) (context, diagnostic, orig_diag_kind);
diagnostics. */
bool show_cwe;
+ /* True if we should print any rules associated with diagnostics. */
+ bool show_rules;
+
/* How should diagnostic_path objects be printed. */
enum diagnostic_path_format path_format;
-fno-diagnostics-show-option -fno-diagnostics-show-caret @gol
-fno-diagnostics-show-labels -fno-diagnostics-show-line-numbers @gol
-fno-diagnostics-show-cwe @gol
+-fno-diagnostics-show-rule @gol
-fdiagnostics-minimum-margin-width=@var{width} @gol
-fdiagnostics-parseable-fixits -fdiagnostics-generate-patch @gol
-fdiagnostics-show-template-tree -fno-elide-type @gol
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-rules
+@opindex fno-diagnostics-show-rules
+@opindex fdiagnostics-show-rules
+Diagnostic messages can optionally have rules associated with them, such
+as from a coding standard, or a specification.
+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
dc->show_cwe = value;
break;
+ case OPT_fdiagnostics_show_rules:
+ dc->show_rules = value;
+ break;
+
case OPT_fdiagnostics_path_format_:
dc->path_format = (enum diagnostic_path_format)value;
break;
void test_cwe (void)
{
char buf[1024];
- gets (buf); /* { dg-warning "never use 'gets' \\\[CWE-242\\\]" } */
+ gets (buf); /* { dg-warning "never use 'gets' \\\[CWE-242\\\] \\\[STR34-C\\\]" } */
}
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;
+
+ /* CWE-242: Use of Inherently Dangerous Function. */
m.add_cwe (242);
+
+ /* Example of a diagnostic_metadata::rule. */
+ diagnostic_metadata::precanned_rule
+ test_rule ("STR34-C", "https://example.com/");
+ m.add_rule (test_rule);
+
warning_meta (&richloc, m, 0,
"never use %qs", "gets");
}
= global_options_init.x_flag_diagnostics_show_line_numbers;
global_dc->show_cwe
= global_options_init.x_flag_diagnostics_show_cwe;
+ global_dc->show_rules
+ = global_options_init.x_flag_diagnostics_show_rules;
global_dc->path_format
= (enum diagnostic_path_format)global_options_init.x_flag_diagnostics_path_format;
global_dc->show_path_depths