@@ -84,22 +84,4 @@ public:
virtual void for_each_plugin (plugin_visitor &v) const = 0;
};
-/* Abstract base class for a diagnostic_context to get at
- information about a specific plugin within a client. */
-
-class diagnostic_client_plugin_info
-{
-public:
- /* For use e.g. by SARIF "name" property (SARIF v2.1.0 section 3.19.8). */
- virtual const char *get_short_name () const = 0;
-
- /* For use e.g. by SARIF "fullName" property
- (SARIF v2.1.0 section 3.19.9). */
- virtual const char *get_full_name () const = 0;
-
- /* For use e.g. by SARIF "version" property
- (SARIF v2.1.0 section 3.19.13). */
- virtual const char *get_version () const = 0;
-};
-
#endif /* ! GCC_DIAGNOSTIC_CLIENT_DATA_HOOKS_H */
new file mode 100644
@@ -0,0 +1,43 @@
+/* Metadata about plugins within a diagnostic client.
+ Copyright (C) 2022 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_CLIENT_PLUGIN_H
+#define GCC_DIAGNOSTIC_CLIENT_PLUGIN_H
+
+/* Abstract base class for a diagnostic_context to get at
+ information about a specific plugin within a client,
+ and for associating plugins with diagnostic metadata. */
+
+class diagnostic_client_plugin_info
+{
+public:
+ /* For use e.g. by SARIF "name" property (SARIF v2.1.0 section 3.19.8). */
+ virtual const char *get_short_name () const = 0;
+
+ /* For use e.g. by SARIF "fullName" property
+ (SARIF v2.1.0 section 3.19.9). */
+ virtual const char *get_full_name () const = 0;
+
+ /* For use e.g. by SARIF "version" property
+ (SARIF v2.1.0 section 3.19.13). */
+ virtual const char *get_version () const = 0;
+};
+
+#endif /* ! GCC_DIAGNOSTIC_CLIENT_PLUGIN_H */
@@ -29,9 +29,26 @@ along with GCC; see the file COPYING3. If not see
#include "cpplib.h"
#include "logical-location.h"
#include "diagnostic-client-data-hooks.h"
+#include "diagnostic-client-plugin.h"
class sarif_builder;
+/* Subclass of json::object for SARIF toolComponent objects
+ (SARIF v2.1.0 section section 3.19), used for the driver
+ and for extensions. */
+
+class sarif_tool_component : public json::object
+{
+public:
+ sarif_tool_component ();
+
+ void lazily_add_rule (char *id, json::object *reporting_desc_obj);
+
+private:
+ hash_set <free_string_hash> m_rule_id_set;
+ json::array *m_rules_arr;
+};
+
/* Subclass of json::object for SARIF result objects
(SARIF v2.1.0 section 3.27. */
@@ -110,6 +127,13 @@ public:
json::object *make_message_object (const char *msg) const;
private:
+ sarif_tool_component *
+ get_plugin_tool_component_object
+ (const diagnostic_client_plugin_info *plugin);
+ void set_result_rule_id (diagnostic_context *context,
+ diagnostic_info *diagnostic,
+ diagnostic_t orig_diag_kind,
+ sarif_result *result_obj);
sarif_result *make_result_object (diagnostic_context *context,
diagnostic_info *diagnostic,
diagnostic_t orig_diag_kind);
@@ -133,12 +157,16 @@ private:
json::object *make_multiformat_message_string (const char *msg) const;
json::object *make_top_level_object (json::array *results);
json::object *make_run_object (json::array *results);
- json::object *make_tool_object () const;
- json::object *make_driver_tool_component_object () const;
+ json::object *make_tool_object ();
+ sarif_tool_component *make_driver_tool_component_object () const;
json::array *maybe_make_taxonomies_array () const;
json::object *maybe_make_cwe_taxonomy_object () const;
json::object *make_tool_component_reference_object_for_cwe () const;
json::object *
+ make_reporting_descriptor_object_for_rule
+ (const diagnostic_metadata::rule &rule,
+ const char *desc);
+ json::object *
make_reporting_descriptor_object_for_warning (diagnostic_context *context,
diagnostic_info *diagnostic,
diagnostic_t orig_diag_kind,
@@ -168,8 +196,11 @@ private:
hash_set <const char *> m_filenames;
bool m_seen_any_relative_paths;
- hash_set <free_string_hash> m_rule_id_set;
- json::array *m_rules_arr;
+
+ sarif_tool_component *m_driver_obj;
+ json::array *m_extensions_arr;
+ hash_map <const diagnostic_client_plugin_info *,
+ sarif_tool_component *> m_plugin_objs;
/* The set of all CWE IDs we've seen, if any. */
hash_set <int_hash <int, 0, 1> > m_cwe_id_set;
@@ -179,6 +210,39 @@ private:
static sarif_builder *the_builder;
+/* class sarif_tool_component : public json::object. */
+
+sarif_tool_component::sarif_tool_component ()
+: m_rule_id_set (),
+ m_rules_arr (new json::array ())
+{
+ /* "rules" property (SARIF v2.1.0 section 3.19.23). */
+ set ("rules", m_rules_arr);
+}
+
+/* Take ownership of ID and REPORTING_DESC_OBJ.
+ Ensure that ID is represented within the rules array,
+ using REPORTING_DESC_OBJ if it isn't. */
+
+void
+sarif_tool_component::lazily_add_rule (char *id,
+ json::object *reporting_desc_obj)
+{
+ if (m_rule_id_set.contains (id))
+ {
+ /* Already seen; clean up redundant entries. */
+ free (id);
+ delete reporting_desc_obj;
+ }
+ else
+ {
+ /* This is the first time we've seen this ruleId. */
+ /* Add to set, taking ownership. */
+ m_rule_id_set.add (id);
+ m_rules_arr->append (reporting_desc_obj);
+ }
+}
+
/* class sarif_result : public json::object. */
/* Handle secondary diagnostics that occur within a diagnostic group.
@@ -221,10 +285,12 @@ sarif_builder::sarif_builder (diagnostic_context *context)
m_results_array (new json::array ()),
m_cur_group_result (NULL),
m_seen_any_relative_paths (false),
- m_rule_id_set (),
- m_rules_arr (new json::array ()),
+ m_driver_obj (NULL),
+ m_extensions_arr (NULL),
m_tabstop (context->tabstop)
{
+ m_driver_obj = make_driver_tool_component_object ();
+ m_extensions_arr = new json::array ();
}
/* Implementation of "end_diagnostic" for SARIF output. */
@@ -320,51 +386,120 @@ make_rule_id_for_diagnostic_kind (diagnostic_t diag_kind)
return rstrip;
}
-/* Make a result object (SARIF v2.1.0 section 3.27) for DIAGNOSTIC. */
+/* Get or create a toolComponent object (SARIF v2.1.0 section 3.19)
+ for PLUGIN, adding to m_extensions_arr and using m_plugin_objs to
+ reuse any existing object for PLUGIN. */
-sarif_result *
-sarif_builder::make_result_object (diagnostic_context *context,
+sarif_tool_component *
+sarif_builder::
+get_plugin_tool_component_object (const diagnostic_client_plugin_info *plugin)
+{
+ if (sarif_tool_component **slot = m_plugin_objs.get (plugin))
+ return *slot;
+
+ sarif_tool_component *plugin_obj = new sarif_tool_component ();
+ m_plugin_objs.put (plugin, plugin_obj);
+ m_extensions_arr->append (plugin_obj);
+
+ /* "name" property (SARIF v2.1.0 section 3.19.8). */
+ if (const char *short_name = plugin->get_short_name ())
+ plugin_obj->set ("name", new json::string (short_name));
+
+ /* "fullName" property (SARIF v2.1.0 section 3.19.9). */
+ if (const char *full_name = plugin->get_full_name ())
+ plugin_obj->set ("fullName", new json::string (full_name));
+
+ /* "version" property (SARIF v2.1.0 section 3.19.13). */
+ if (const char *version = plugin->get_version ())
+ plugin_obj->set ("version", new json::string (version));
+
+ return plugin_obj;
+}
+
+/* If DIAGNOSTIC has any associated rules, get the first one. */
+
+static const diagnostic_metadata::rule *
+maybe_get_first_rule (diagnostic_info *diagnostic)
+{
+ if (!diagnostic->metadata)
+ return NULL;
+ if (diagnostic->metadata->get_num_rules () == 0)
+ return NULL;
+ return &diagnostic->metadata->get_rule (0);
+}
+
+/* Set "ruleId" property of RESULT_OBJ (SARIF v2.1.0 section 3.27.5).
+ Ensure that there is such a rule within the component, and that such
+ a component exists (either for the driver, or any plugin). */
+
+void
+sarif_builder::set_result_rule_id (diagnostic_context *context,
diagnostic_info *diagnostic,
- diagnostic_t orig_diag_kind)
+ diagnostic_t orig_diag_kind,
+ sarif_result *result_obj)
{
- sarif_result *result_obj = new sarif_result ();
+ /* Determine which component we should search for within/add the
+ rule to. */
+ sarif_tool_component *component_obj = m_driver_obj;
+ if (diagnostic->metadata)
+ if (const diagnostic_client_plugin_info *plugin
+ = diagnostic->metadata->get_plugin ())
+ component_obj = get_plugin_tool_component_object (plugin);
/* "ruleId" property (SARIF v2.1.0 section 3.27.5). */
- /* Ideally we'd have an option_name for these. */
+ if (const diagnostic_metadata::rule *rule
+ = maybe_get_first_rule (diagnostic))
+ if (char *desc = rule->make_description ())
+ {
+ /* Lazily create reportingDescriptor objects for the rule
+ and add to the component.
+ Set ruleId referencing them. */
+ result_obj->set ("ruleId", new json::string (desc));
+ component_obj->lazily_add_rule
+ (desc,
+ make_reporting_descriptor_object_for_rule (*rule, desc));
+ return;
+ }
+
+ /* Otherwise, try to use the option_name for these. */
if (char *option_text
= context->option_name (context, diagnostic->option_index,
orig_diag_kind, diagnostic->kind))
{
- /* Lazily create reportingDescriptor objects for and add to m_rules_arr.
+ /* Lazily create reportingDescriptor objects for the warning
+ and add to the component.
Set ruleId referencing them. */
result_obj->set ("ruleId", new json::string (option_text));
- if (m_rule_id_set.contains (option_text))
- free (option_text);
- else
- {
- /* This is the first time we've seen this ruleId. */
- /* Add to set, taking ownership. */
- m_rule_id_set.add (option_text);
-
- json::object *reporting_desc_obj
- = make_reporting_descriptor_object_for_warning (context,
- diagnostic,
- orig_diag_kind,
- option_text);
- m_rules_arr->append (reporting_desc_obj);
- }
- }
- else
- {
- /* Otherwise, we have an "error" or a stray "note"; use the
- diagnostic kind as the ruleId, so that the result object at least
- has a ruleId.
- We don't bother creating reportingDescriptor objects for these. */
- char *rule_id = make_rule_id_for_diagnostic_kind (orig_diag_kind);
- result_obj->set ("ruleId", new json::string (rule_id));
- free (rule_id);
+ component_obj->lazily_add_rule
+ (option_text,
+ make_reporting_descriptor_object_for_warning (context,
+ diagnostic,
+ orig_diag_kind,
+ option_text));
+ return;
}
+ /* Otherwise, we have a "warning" without an option, an "error" or a stray
+ "note"; use the diagnostic kind as the ruleId, so that the result object
+ at least has a ruleId.
+ We don't bother creating reportingDescriptor objects for these. */
+ char *rule_id = make_rule_id_for_diagnostic_kind (orig_diag_kind);
+ result_obj->set ("ruleId", new json::string (rule_id));
+ free (rule_id);
+}
+
+/* Make a result object (SARIF v2.1.0 section 3.27) for DIAGNOSTIC. */
+
+sarif_result *
+sarif_builder::make_result_object (diagnostic_context *context,
+ diagnostic_info *diagnostic,
+ diagnostic_t orig_diag_kind)
+{
+ sarif_result *result_obj = new sarif_result ();
+
+ /* "ruleId" property (SARIF v2.1.0 section 3.27.5). */
+ set_result_rule_id (context, diagnostic, orig_diag_kind, result_obj);
+
/* "taxa" property (SARIF v2.1.0 section 3.27.8). */
if (diagnostic->metadata)
if (int cwe_id = diagnostic->metadata->get_cwe ())
@@ -424,6 +559,32 @@ sarif_builder::make_result_object (diagnostic_context *context,
return result_obj;
}
+/* Make a reportingDescriptor object (SARIF v2.1.0 section 3.49)
+ for RULE, with DESC. */
+
+json::object *
+sarif_builder::
+make_reporting_descriptor_object_for_rule (const diagnostic_metadata::rule &rule,
+ const char *desc)
+{
+ json::object *reporting_desc = new json::object ();
+
+ /* "id" property (SARIF v2.1.0 section 3.49.3). */
+ reporting_desc->set ("id", new json::string (desc));
+
+ /* We don't implement "name" property (SARIF v2.1.0 section 3.49.7), since
+ it seems redundant compared to "id". */
+
+ /* "helpUri" property (SARIF v2.1.0 section 3.49.12). */
+ if (char *url = rule.make_url ())
+ {
+ reporting_desc->set ("helpUri", new json::string (url));
+ free (url);
+ }
+
+ return reporting_desc;
+}
+
/* Make a reportingDescriptor object (SARIF v2.1.0 section 3.49)
for a GCC warning. */
@@ -1089,16 +1250,16 @@ sarif_builder::make_run_object (json::array *results)
/* Make a tool object (SARIF v2.1.0 section 3.18). */
json::object *
-sarif_builder::make_tool_object () const
+sarif_builder::make_tool_object ()
{
json::object *tool_obj = new json::object ();
/* "driver" property (SARIF v2.1.0 section 3.18.2). */
- json::object *driver_obj = make_driver_tool_component_object ();
- tool_obj->set ("driver", driver_obj);
+ tool_obj->set ("driver", m_driver_obj);
/* Report plugins via the "extensions" property
(SARIF v2.1.0 section 3.18.3). */
+ tool_obj->set ("extensions", m_extensions_arr);
if (m_context->m_client_data_hooks)
if (const client_version_info *vinfo
= m_context->m_client_data_hooks->get_any_version_info ())
@@ -1106,36 +1267,19 @@ sarif_builder::make_tool_object () const
class my_plugin_visitor : public client_version_info :: plugin_visitor
{
public:
+ my_plugin_visitor (sarif_builder *builder)
+ : m_builder (builder)
+ {}
+
void on_plugin (const diagnostic_client_plugin_info &p) final override
{
- /* Create a toolComponent object (SARIF v2.1.0 section 3.19)
- for the plugin. */
- json::object *plugin_obj = new json::object ();
- m_plugin_objs.safe_push (plugin_obj);
-
- /* "name" property (SARIF v2.1.0 section 3.19.8). */
- if (const char *short_name = p.get_short_name ())
- plugin_obj->set ("name", new json::string (short_name));
-
- /* "fullName" property (SARIF v2.1.0 section 3.19.9). */
- if (const char *full_name = p.get_full_name ())
- plugin_obj->set ("fullName", new json::string (full_name));
-
- /* "version" property (SARIF v2.1.0 section 3.19.13). */
- if (const char *version = p.get_version ())
- plugin_obj->set ("version", new json::string (version));
+ m_builder->get_plugin_tool_component_object (&p);
}
- auto_vec <json::object *> m_plugin_objs;
+ private:
+ sarif_builder *m_builder;
};
- my_plugin_visitor v;
+ my_plugin_visitor v (this);
vinfo->for_each_plugin (v);
- if (v.m_plugin_objs.length () > 0)
- {
- json::array *extensions_arr = new json::array ();
- tool_obj->set ("extensions", extensions_arr);
- for (auto iter : v.m_plugin_objs)
- extensions_arr->append (iter);
- }
}
/* Perhaps we could also show GMP, MPFR, MPC, isl versions as other
@@ -1147,10 +1291,10 @@ sarif_builder::make_tool_object () const
/* Make a toolComponent object (SARIF v2.1.0 section 3.19) for what SARIF
calls the "driver" (see SARIF v2.1.0 section 3.18.1). */
-json::object *
+sarif_tool_component *
sarif_builder::make_driver_tool_component_object () const
{
- json::object *driver_obj = new json::object ();
+ sarif_tool_component *driver_obj = new sarif_tool_component ();
if (m_context->m_client_data_hooks)
if (const client_version_info *vinfo
@@ -1179,9 +1323,6 @@ sarif_builder::make_driver_tool_component_object () const
}
}
- /* "rules" property (SARIF v2.1.0 section 3.19.23). */
- driver_obj->set ("rules", m_rules_arr);
-
return driver_obj;
}
@@ -21,11 +21,16 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_DIAGNOSTIC_METADATA_H
#define GCC_DIAGNOSTIC_METADATA_H
+class diagnostic_client_plugin_info;
+
/* A bundle of additional metadata that can be associated with a
diagnostic.
- This supports an optional CWE identifier, and zero or more
- "rules". */
+ This supports:
+ - an optional plugin associated with this diagnostic
+ - an optional CWE identifier
+ - zero or more "rules" (such as rules within a coding standard,
+ or within a specification). */
class diagnostic_metadata
{
@@ -62,7 +67,15 @@ class diagnostic_metadata
const char *m_url;
};
- diagnostic_metadata () : m_cwe (0) {}
+ /* Ctors. */
+ diagnostic_metadata ()
+ : m_plugin (NULL),
+ m_cwe (0)
+ {}
+ diagnostic_metadata (const diagnostic_client_plugin_info *plugin)
+ : m_plugin (plugin),
+ m_cwe (0)
+ {}
void add_cwe (int cwe) { m_cwe = cwe; }
int get_cwe () const { return m_cwe; }
@@ -74,10 +87,13 @@ class diagnostic_metadata
m_rules.safe_push (&r);
}
+ const diagnostic_client_plugin_info *get_plugin () const { return m_plugin; }
+
unsigned get_num_rules () const { return m_rules.length (); }
const rule &get_rule (unsigned idx) const { return *(m_rules[idx]); }
private:
+ const diagnostic_client_plugin_info *m_plugin;
int m_cwe;
auto_vec<const rule *> m_rules;
};
@@ -102,11 +102,20 @@ the parser. The arguments to @code{plugin_init} are:
@item @code{version}: GCC version.
@end itemize
-The @code{plugin_info} struct is defined as follows:
+The @code{plugin_info} class is defined as follows:
@smallexample
-struct plugin_name_args
+class plugin_name_args : public diagnostic_client_plugin_info
@{
+ public:
+ plugin_name_args (char *base_name_,
+ const char *full_name_);
+
+ /* Implementation of diagnostic_client_plugin_info. */
+ const char *get_short_name () const final override;
+ const char *get_full_name () const final override;
+ const char *get_version () const final override;
+
char *base_name; /* Short name of the plugin
(filename without .so suffix). */
const char *full_name; /* Path to the plugin as specified with
@@ -149,7 +158,7 @@ recommended version check to perform looks like
...
int
-plugin_init (struct plugin_name_args *plugin_info,
+plugin_init (plugin_name_args *plugin_info,
struct plugin_gcc_version *version)
@{
if (!plugin_default_version_check (version, &gcc_version))
@@ -295,7 +304,7 @@ struct register_pass_info
/* Sample plugin code that registers a new pass. */
int
-plugin_init (struct plugin_name_args *plugin_info,
+plugin_init (plugin_name_args *plugin_info,
struct plugin_gcc_version *version)
@{
struct register_pass_info pass_info;
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "options.h"
#include "tree-pass.h"
#include "diagnostic-core.h"
+#include "diagnostic-client-plugin.h"
#include "flags.h"
#include "intl.h"
#include "plugin.h"
@@ -124,6 +125,39 @@ static const char *str_plugin_init_func_name = "plugin_init";
static const char *str_license = "plugin_is_GPL_compatible";
#endif
+/* class plugin_name_args : public diagnostic_client_plugin_info. */
+
+/* plugin_name_args's ctor. */
+
+plugin_name_args::plugin_name_args (char *base_name_,
+ const char *full_name_)
+: base_name (base_name_),
+ full_name (full_name_),
+ argc (0),
+ argv (NULL),
+ version (NULL),
+ help (NULL)
+{
+}
+
+const char *
+plugin_name_args::get_short_name () const
+{
+ return base_name;
+}
+
+const char *
+plugin_name_args::get_full_name () const
+{
+ return full_name;
+}
+
+const char *
+plugin_name_args::get_version () const
+{
+ return version;
+}
+
/* Helper function for hashing the base_name of the plugin_name_args
structure to be inserted into the hash table. */
@@ -236,7 +270,7 @@ add_new_plugin (const char* plugin_name)
return;
}
- plugin = XCNEW (struct plugin_name_args);
+ plugin = new plugin_name_args (base_name, plugin_name);
plugin->base_name = base_name;
plugin->full_name = plugin_name;
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#define PLUGIN_H
#include "highlev-plugin-common.h"
+#include "diagnostic-client-plugin.h"
/* Event names. */
enum plugin_event
@@ -65,8 +66,17 @@ struct plugin_gcc_version
};
/* Object that keeps track of the plugin name and its arguments. */
-struct plugin_name_args
+class plugin_name_args : public diagnostic_client_plugin_info
{
+ public:
+ plugin_name_args (char *base_name_,
+ const char *full_name_);
+
+ /* Implementation of diagnostic_client_plugin_info. */
+ const char *get_short_name () const final override;
+ const char *get_full_name () const final override;
+ const char *get_version () const final override;
+
char *base_name; /* Short name of the plugin (filename without
.so suffix). */
const char *full_name; /* Path to the plugin as specified with
new file mode 100644
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-fdiagnostics-format=sarif-file" } */
+
+extern char *gets (char *s);
+
+void test_cwe (void)
+{
+ char buf[1024];
+ gets (buf);
+}
+
+/* Verify that some JSON was written to a file with the expected name. */
+
+/* We expect various properties.
+ The indentation here reflects the expected hierarchy, though these tests
+ don't check for that, merely the string fragments we expect.
+ { dg-final { scan-sarif-file "\"version\": \"2.1.0\"" } }
+ { dg-final { scan-sarif-file "\"runs\": \\\[" } }
+ { dg-final { scan-sarif-file "\"tool\": " } }
+ { dg-final { scan-sarif-file "\"driver\": " } }
+ { dg-final { scan-sarif-file "\"name\": \"GNU C" } }
+
+ { dg-final { scan-sarif-file "\"rules\": \\\[" } }
+ { dg-final { scan-sarif-file "\"id\": \"STR34-C\"" } }
+ { dg-final { scan-sarif-file "\"helpUri\": \"https://example.com/\"" } }
+
+ Ideally we would verify that the above rule is within the extension,
+ rather than the driver. Unfortunately we don't have a way to
+ do this at present.
+
+ { dg-final { scan-sarif-file "\"extensions\": \\\[" } }
+ { dg-final { scan-sarif-file "\"name\": \"diagnostic_plugin_test_metadata\"" } }
+ { dg-final { scan-sarif-file "\"results\": \\\[" } }
+ { dg-final { scan-sarif-file "\"level\": \"warning\"" } }
+ { dg-final { scan-sarif-file "\"message\": " } }
+ { dg-final { scan-sarif-file "\"text\": \"never use 'gets'\"" } }
+ { dg-final { scan-sarif-file "\"taxa\": \\\[" } }
+ { dg-final { scan-sarif-file "\"id\": \"242\"" } }
+*/
@@ -32,6 +32,8 @@
int plugin_is_GPL_compatible;
+static diagnostic_client_plugin_info *diag_plugin_info;
+
const pass_data pass_data_test_metadata =
{
GIMPLE_PASS, /* type */
@@ -106,7 +108,7 @@ pass_test_metadata::execute (function *fun)
if (gcall *call = check_for_named_call (stmt, "gets", 1))
{
gcc_rich_location richloc (gimple_location (call));
- diagnostic_metadata m;
+ diagnostic_metadata m (diag_plugin_info);
/* CWE-242: Use of Inherently Dangerous Function. */
m.add_cwe (242);
@@ -136,6 +138,8 @@ plugin_init (struct plugin_name_args *plugin_info,
if (!plugin_default_version_check (version, &gcc_version))
return 1;
+ diag_plugin_info = plugin_info;
+
pass_info.pass = new pass_test_metadata (g);
pass_info.reference_pass_name = "ssa";
pass_info.ref_pass_instance_number = 1;
@@ -96,7 +96,9 @@ 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 } \
+ { diagnostic_plugin_test_metadata.c \
+ diagnostic-test-metadata.c \
+ diagnostic-test-metadata-sarif.c } \
{ diagnostic_plugin_test_paths.c \
diagnostic-test-paths-1.c \
diagnostic-test-paths-2.c \
@@ -27,41 +27,10 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h"
#include "tree-logical-location.h"
#include "diagnostic-client-data-hooks.h"
+#include "diagnostic-client-plugin.h"
#include "langhooks.h"
#include "plugin.h"
-/* Concrete class for supplying a diagnostic_context with information
- about a specific plugin within the client, when the client is the
- compiler (i.e. a GCC plugin). */
-
-class compiler_diagnostic_client_plugin_info
- : public diagnostic_client_plugin_info
-{
-public:
- compiler_diagnostic_client_plugin_info (const plugin_name_args *args)
- : m_args (args)
- {
- }
-
- const char *get_short_name () const final override
- {
- return m_args->base_name;
- }
-
- const char *get_full_name () const final override
- {
- return m_args->full_name;
- }
-
- const char *get_version () const final override
- {
- return m_args->version;
- }
-
-private:
- const plugin_name_args *m_args;
-};
-
/* Concrete subclass of client_version_info for use by compilers proper,
(i.e. using lang_hooks, and with knowledge of GCC plugins). */
@@ -103,10 +72,9 @@ private:
on_plugin_cb (const plugin_name_args *args,
void *user_data)
{
- compiler_diagnostic_client_plugin_info cpi (args);
client_version_info::plugin_visitor *visitor
= (client_version_info::plugin_visitor *)user_data;
- visitor->on_plugin (cpi);
+ visitor->on_plugin (*args);
}
};
gcc/ChangeLog: * diagnostic-client-data-hooks.h (class diagnostic_client_plugin_info): Move to... * diagnostic-client-plugin.h: ...this new file. * diagnostic-format-sarif.cc: Include "diagnostic-client-plugin.h". (class sarif_tool_component): New class. (sarif_builder::m_rule_id_set): Move field to sarif_tool_component. (sarif_builder::m_rules_arr): Likewise. (sarif_builder::m_driver_obj): New field. (sarif_builder::m_extensions_arr): New field. (sarif_builder::m_plugin_objs): New field. (sarif_tool_component::sarif_tool_component): New. (sarif_tool_component::lazily_add_rule): New. (sarif_builder::sarif_builder): Update for changes to fields. (sarif_builder::get_plugin_tool_component_object): New, adapted from code within sarif_builder::make_tool_object. (maybe_get_first_rule): New. (sarif_builder::set_result_rule_id): New, adapted from code within sarif_builder::make_result_object. (sarif_builder::make_result_object): Move rule_id logic to sarif_builder::set_result_rule_id. (sarif_builder::make_reporting_descriptor_object_for_rule): New. (sarif_builder::make_tool_object): Drop "const" qualifier. Use the m_driver_obj and m_extensions_arr created in the ctor. Update the visitor to call get_plugin_tool_component_object, rather than duplicate the toolComponent creation logic. (sarif_builder::make_driver_tool_component_object): Convert return type to sarif_tool_component *. Move setting of "rules" property to sarif_tool_component ctor. * diagnostic-metadata.h (class diagnostic_client_plugin_info): New forward decl. (diagnostic_metadata::diagnostic_metadata): Add overloaded ctor. Initialize m_plugin. (diagnostic_metadata::get_plugin): New. (diagnostic_metadata::m_plugin): New field. * doc/plugins.texi (Plugin initialization): Update. * plugin.cc: Include "diagnostic-client-plugin.h". (plugin_name_args::plugin_name_args): New ctor. (plugin_name_args::get_short_name): New. (plugin_name_args::get_full_name): New. (plugin_name_args::get_version): New. (add_new_plugin): Rewrite creation of "plugin" to use new with a ctor. * plugin.h: Include "diagnostic-client-plugin.h". (struct plugin_name_args): Convert to... (class plugin_name_args): ...this, deriving it from diagnostic_client_plugin_info. (plugin_name_args::plugin_name_args): New ctor decl. (plugin_name_args::get_short_name): New decl. (plugin_name_args::get_full_name): New decl. (plugin_name_args::get_version): New decl. * tree-diagnostic-client-data-hooks.cc: Include "diagnostic-client-plugin.h". (class compiler_diagnostic_client_plugin_info): Delete. (compiler_version_info::on_plugin_cb): Pass plugin_name_args to the visitor, now that the former is a diagnostic_client_plugin_info. gcc/testsuite/ChangeLog: * gcc.dg/plugin/diagnostic-test-metadata-sarif.c: New test. * gcc.dg/plugin/diagnostic_plugin_test_metadata.c (diag_plugin_info): New global. (pass_test_metadata::execute): Pass it to metadata. (plugin_init): Initialize it. * gcc.dg/plugin/plugin.exp (plugin_test_list): Add diagnostic-test-metadata-sarif.c to diagnostic_plugin_test_metadata.c. Signed-off-by: David Malcolm <dmalcolm@redhat.com> --- gcc/diagnostic-client-data-hooks.h | 18 -- gcc/diagnostic-client-plugin.h | 43 +++ gcc/diagnostic-format-sarif.cc | 283 +++++++++++++----- gcc/diagnostic-metadata.h | 22 +- gcc/doc/plugins.texi | 17 +- gcc/plugin.cc | 36 ++- gcc/plugin.h | 12 +- .../plugin/diagnostic-test-metadata-sarif.c | 39 +++ .../plugin/diagnostic_plugin_test_metadata.c | 6 +- gcc/testsuite/gcc.dg/plugin/plugin.exp | 4 +- gcc/tree-diagnostic-client-data-hooks.cc | 36 +-- 11 files changed, 382 insertions(+), 134 deletions(-) create mode 100644 gcc/diagnostic-client-plugin.h create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata-sarif.c