aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/analyzer/analyzer.h1
-rw-r--r--gcc/analyzer/bounds-checking.cc130
-rw-r--r--gcc/analyzer/call-details.cc8
-rw-r--r--gcc/analyzer/diagnostic-manager.cc53
-rw-r--r--gcc/analyzer/diagnostic-manager.h2
-rw-r--r--gcc/analyzer/engine.cc15
-rw-r--r--gcc/analyzer/infinite-loop.cc9
-rw-r--r--gcc/analyzer/infinite-recursion.cc9
-rw-r--r--gcc/analyzer/kf-analyzer.cc4
-rw-r--r--gcc/analyzer/kf.cc32
-rw-r--r--gcc/analyzer/pending-diagnostic.cc45
-rw-r--r--gcc/analyzer/pending-diagnostic.h56
-rw-r--r--gcc/analyzer/region-model.cc123
-rw-r--r--gcc/analyzer/region.cc1
-rw-r--r--gcc/analyzer/sm-fd.cc75
-rw-r--r--gcc/analyzer/sm-file.cc23
-rw-r--r--gcc/analyzer/sm-malloc.cc118
-rw-r--r--gcc/analyzer/sm-pattern-test.cc8
-rw-r--r--gcc/analyzer/sm-sensitive.cc12
-rw-r--r--gcc/analyzer/sm-signal.cc11
-rw-r--r--gcc/analyzer/sm-taint.cc212
-rw-r--r--gcc/analyzer/store.cc1
-rw-r--r--gcc/analyzer/varargs.cc39
-rw-r--r--gcc/diagnostic-core.h6
-rw-r--r--gcc/diagnostic-format-sarif.cc22
-rw-r--r--gcc/diagnostic-metadata.h10
-rw-r--r--gcc/diagnostic.cc12
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-accept.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-bind.c4
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-socket-misuse.c2
-rw-r--r--gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.c10
-rw-r--r--gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c28
32 files changed, 550 insertions, 533 deletions
diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index cf32d4b..3115f87 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -94,6 +94,7 @@ class bounded_ranges_manager;
struct pending_location;
class pending_diagnostic;
class pending_note;
+class saved_diagnostic;
struct event_loc_info;
class checker_event;
class state_change_event;
diff --git a/gcc/analyzer/bounds-checking.cc b/gcc/analyzer/bounds-checking.cc
index 583b5ab..cc43ecc 100644
--- a/gcc/analyzer/bounds-checking.cc
+++ b/gcc/analyzer/bounds-checking.cc
@@ -30,7 +30,6 @@ along with GCC; see the file COPYING3. If not see
#include "gimple.h"
#include "gimple-iterator.h"
#include "diagnostic-core.h"
-#include "diagnostic-metadata.h"
#include "diagnostic-diagram.h"
#include "analyzer/analyzer.h"
#include "analyzer/analyzer-logging.h"
@@ -119,10 +118,10 @@ protected:
}
void
- maybe_show_notes (location_t loc, logger *logger) const
+ maybe_show_notes (diagnostic_emission_context &ctxt) const
{
- maybe_describe_array_bounds (loc);
- maybe_show_diagram (logger);
+ maybe_describe_array_bounds (ctxt.get_location ());
+ maybe_show_diagram (ctxt.get_logger ());
}
/* Potentially add a note about valid ways to index this array, such
@@ -281,27 +280,22 @@ public:
return "concrete_buffer_overflow";
}
- bool emit (rich_location *rich_loc,
- logger *logger) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
bool warned;
switch (get_memory_space ())
{
default:
- m.add_cwe (787);
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "buffer overflow");
+ ctxt.add_cwe (787);
+ warned = ctxt.warn ("buffer overflow");
break;
case MEMSPACE_STACK:
- m.add_cwe (121);
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "stack-based buffer overflow");
+ ctxt.add_cwe (121);
+ warned = ctxt.warn ("stack-based buffer overflow");
break;
case MEMSPACE_HEAP:
- m.add_cwe (122);
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "heap-based buffer overflow");
+ ctxt.add_cwe (122);
+ warned = ctxt.warn ("heap-based buffer overflow");
break;
}
@@ -312,25 +306,25 @@ public:
unsigned HOST_WIDE_INT num_bad_bytes
= m_out_of_bounds_range.m_size_in_bytes.to_uhwi ();
if (m_diag_arg)
- inform_n (rich_loc->get_loc (),
+ inform_n (ctxt.get_location (),
num_bad_bytes,
"write of %wu byte to beyond the end of %qE",
"write of %wu bytes to beyond the end of %qE",
num_bad_bytes,
m_diag_arg);
else
- inform_n (rich_loc->get_loc (),
+ inform_n (ctxt.get_location (),
num_bad_bytes,
"write of %wu byte to beyond the end of the region",
"write of %wu bytes to beyond the end of the region",
num_bad_bytes);
}
else if (m_diag_arg)
- inform (rich_loc->get_loc (),
+ inform (ctxt.get_location (),
"write to beyond the end of %qE",
m_diag_arg);
- maybe_show_notes (rich_loc->get_loc (), logger);
+ maybe_show_notes (ctxt);
}
return warned;
@@ -388,24 +382,20 @@ public:
return "concrete_buffer_over_read";
}
- bool emit (rich_location *rich_loc, logger *logger) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
bool warned;
- m.add_cwe (126);
+ ctxt.add_cwe (126);
switch (get_memory_space ())
{
default:
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "buffer over-read");
+ warned = ctxt.warn ("buffer over-read");
break;
case MEMSPACE_STACK:
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "stack-based buffer over-read");
+ warned = ctxt.warn ("stack-based buffer over-read");
break;
case MEMSPACE_HEAP:
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "heap-based buffer over-read");
+ warned = ctxt.warn ("heap-based buffer over-read");
break;
}
@@ -416,25 +406,25 @@ public:
unsigned HOST_WIDE_INT num_bad_bytes
= m_out_of_bounds_range.m_size_in_bytes.to_uhwi ();
if (m_diag_arg)
- inform_n (rich_loc->get_loc (),
+ inform_n (ctxt.get_location (),
num_bad_bytes,
"read of %wu byte from after the end of %qE",
"read of %wu bytes from after the end of %qE",
num_bad_bytes,
m_diag_arg);
else
- inform_n (rich_loc->get_loc (),
+ inform_n (ctxt.get_location (),
num_bad_bytes,
"read of %wu byte from after the end of the region",
"read of %wu bytes from after the end of the region",
num_bad_bytes);
}
else if (m_diag_arg)
- inform (rich_loc->get_loc (),
+ inform (ctxt.get_location (),
"read from after the end of %qE",
m_diag_arg);
- maybe_show_notes (rich_loc->get_loc (), logger);
+ maybe_show_notes (ctxt);
}
return warned;
@@ -493,28 +483,24 @@ public:
return "concrete_buffer_underwrite";
}
- bool emit (rich_location *rich_loc, logger *logger) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
bool warned;
- m.add_cwe (124);
+ ctxt.add_cwe (124);
switch (get_memory_space ())
{
default:
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "buffer underwrite");
+ warned = ctxt.warn ("buffer underwrite");
break;
case MEMSPACE_STACK:
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "stack-based buffer underwrite");
+ warned = ctxt.warn ("stack-based buffer underwrite");
break;
case MEMSPACE_HEAP:
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "heap-based buffer underwrite");
+ warned = ctxt.warn ("heap-based buffer underwrite");
break;
}
if (warned)
- maybe_show_notes (rich_loc->get_loc (), logger);
+ maybe_show_notes (ctxt);
return warned;
}
@@ -568,28 +554,24 @@ public:
return "concrete_buffer_under_read";
}
- bool emit (rich_location *rich_loc, logger *logger) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
bool warned;
- m.add_cwe (127);
+ ctxt.add_cwe (127);
switch (get_memory_space ())
{
default:
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "buffer under-read");
+ warned = ctxt.warn ("buffer under-read");
break;
case MEMSPACE_STACK:
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "stack-based buffer under-read");
+ warned = ctxt.warn ("stack-based buffer under-read");
break;
case MEMSPACE_HEAP:
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "heap-based buffer under-read");
+ warned = ctxt.warn ("heap-based buffer under-read");
break;
}
if (warned)
- maybe_show_notes (rich_loc->get_loc (), logger);
+ maybe_show_notes (ctxt);
return warned;
}
@@ -679,30 +661,26 @@ public:
return "symbolic_buffer_overflow";
}
- bool emit (rich_location *rich_loc, logger *logger) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
bool warned;
switch (get_memory_space ())
{
default:
- m.add_cwe (787);
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "buffer overflow");
+ ctxt.add_cwe (787);
+ warned = ctxt.warn ("buffer overflow");
break;
case MEMSPACE_STACK:
- m.add_cwe (121);
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "stack-based buffer overflow");
+ ctxt.add_cwe (121);
+ warned = ctxt.warn ("stack-based buffer overflow");
break;
case MEMSPACE_HEAP:
- m.add_cwe (122);
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "heap-based buffer overflow");
+ ctxt.add_cwe (122);
+ warned = ctxt.warn ("heap-based buffer overflow");
break;
}
if (warned)
- maybe_show_notes (rich_loc->get_loc (), logger);
+ maybe_show_notes (ctxt);
return warned;
}
@@ -796,31 +774,27 @@ public:
return "symbolic_buffer_over_read";
}
- bool emit (rich_location *rich_loc, logger *logger) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
- m.add_cwe (126);
+ ctxt.add_cwe (126);
bool warned;
switch (get_memory_space ())
{
default:
- m.add_cwe (787);
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "buffer over-read");
+ ctxt.add_cwe (787);
+ warned = ctxt.warn ("buffer over-read");
break;
case MEMSPACE_STACK:
- m.add_cwe (121);
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "stack-based buffer over-read");
+ ctxt.add_cwe (121);
+ warned = ctxt.warn ("stack-based buffer over-read");
break;
case MEMSPACE_HEAP:
- m.add_cwe (122);
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "heap-based buffer over-read");
+ ctxt.add_cwe (122);
+ warned = ctxt.warn ("heap-based buffer over-read");
break;
}
if (warned)
- maybe_show_notes (rich_loc->get_loc (), logger);
+ maybe_show_notes (ctxt);
return warned;
}
diff --git a/gcc/analyzer/call-details.cc b/gcc/analyzer/call-details.cc
index 9480f03..c5ae2dc 100644
--- a/gcc/analyzer/call-details.cc
+++ b/gcc/analyzer/call-details.cc
@@ -445,14 +445,12 @@ public:
return OPT_Wanalyzer_overlapping_buffers;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
auto_diagnostic_group d;
- bool warned;
- warned = warning_at (rich_loc, get_controlling_option (),
- "overlapping buffers passed as arguments to %qD",
- m_fndecl);
+ bool warned = ctxt.warn ("overlapping buffers passed as arguments to %qD",
+ m_fndecl);
// TODO: draw a picture?
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index a6755f2..ecd5737 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/checker-path.h"
#include "analyzer/reachability.h"
#include "make-unique.h"
+#include "diagnostic-format-sarif.h"
#if ENABLE_ANALYZER
@@ -1018,6 +1019,31 @@ saved_diagnostic::emit_any_notes () const
pn->emit ();
}
+/* For SARIF output, add additional properties to the "result" object
+ for this diagnostic.
+ This extra data is intended for use when debugging the analyzer. */
+
+void
+saved_diagnostic::maybe_add_sarif_properties (sarif_object &result_obj) const
+{
+ sarif_property_bag &props = result_obj.get_or_create_properties ();
+#define PROPERTY_PREFIX "gcc/analyzer/saved_diagnostic/"
+ if (m_sm)
+ props.set_string (PROPERTY_PREFIX "sm", m_sm->get_name ());
+ props.set_integer (PROPERTY_PREFIX "enode", m_enode->m_index);
+ props.set_integer (PROPERTY_PREFIX "snode", m_snode->m_index);
+ if (m_sval)
+ props.set (PROPERTY_PREFIX "sval", m_sval->to_json ());
+ if (m_state)
+ props.set (PROPERTY_PREFIX "state", m_state->to_json ());
+ if (m_best_epath)
+ props.set (PROPERTY_PREFIX "idx", new json::integer_number (m_idx));
+#undef PROPERTY_PREFIX
+
+ /* Potentially add pending_diagnostic-specific properties. */
+ m_d->maybe_add_sarif_properties (result_obj);
+}
+
/* State for building a checker_path from a particular exploded_path.
In particular, this precomputes reachability information: the set of
source enodes for which a path be found to the diagnostic enode. */
@@ -1498,6 +1524,29 @@ diagnostic_manager::emit_saved_diagnostics (const exploded_graph &eg)
best_candidates.emit_best (this, eg);
}
+/* Custom subclass of diagnostic_metadata which, for SARIF output,
+ populates the property bag of the diagnostic's "result" object
+ with information from the saved_diagnostic and the
+ pending_diagnostic. */
+
+class pending_diagnostic_metadata : public diagnostic_metadata
+{
+public:
+ pending_diagnostic_metadata (const saved_diagnostic &sd)
+ : m_sd (sd)
+ {
+ }
+
+ void
+ maybe_add_sarif_properties (sarif_object &result_obj) const override
+ {
+ m_sd.maybe_add_sarif_properties (result_obj);
+ }
+
+private:
+ const saved_diagnostic &m_sd;
+};
+
/* Given a saved_diagnostic SD with m_best_epath through EG,
create an checker_path of suitable events and use it to call
SD's underlying pending_diagnostic "emit" vfunc to emit a diagnostic. */
@@ -1563,7 +1612,9 @@ diagnostic_manager::emit_saved_diagnostic (const exploded_graph &eg,
auto_diagnostic_group d;
auto_cfun sentinel (sd.m_snode->m_fun);
- if (sd.m_d->emit (&rich_loc, get_logger ()))
+ pending_diagnostic_metadata m (sd);
+ diagnostic_emission_context diag_ctxt (sd, rich_loc, m, get_logger ());
+ if (sd.m_d->emit (diag_ctxt))
{
sd.emit_any_notes ();
diff --git a/gcc/analyzer/diagnostic-manager.h b/gcc/analyzer/diagnostic-manager.h
index 27ab9ed..b6d6f08 100644
--- a/gcc/analyzer/diagnostic-manager.h
+++ b/gcc/analyzer/diagnostic-manager.h
@@ -67,6 +67,8 @@ public:
void emit_any_notes () const;
+ void maybe_add_sarif_properties (sarif_object &result_obj) const;
+
//private:
const state_machine *m_sm;
const exploded_node *m_enode;
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index b4e855f..1f930a2 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -1811,13 +1811,11 @@ public:
return OPT_Wanalyzer_stale_setjmp_buffer;
}
- bool emit (rich_location *richloc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- return warning_at
- (richloc, get_controlling_option (),
- "%qs called after enclosing function of %qs has returned",
- get_user_facing_name (m_longjmp_call),
- get_user_facing_name (m_setjmp_call));
+ return ctxt.warn ("%qs called after enclosing function of %qs has returned",
+ get_user_facing_name (m_longjmp_call),
+ get_user_facing_name (m_setjmp_call));
}
const char *get_kind () const final override
@@ -3982,10 +3980,9 @@ public:
return OPT_Wanalyzer_jump_through_null;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- return warning_at (rich_loc, get_controlling_option (),
- "jump through null pointer");
+ return ctxt.warn ("jump through null pointer");
}
label_text describe_final_event (const evdesc::final_event &ev) final override
diff --git a/gcc/analyzer/infinite-loop.cc b/gcc/analyzer/infinite-loop.cc
index 771d698..c47ce1c 100644
--- a/gcc/analyzer/infinite-loop.cc
+++ b/gcc/analyzer/infinite-loop.cc
@@ -32,7 +32,6 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-core.h"
#include "diagnostic-event-id.h"
#include "diagnostic-path.h"
-#include "diagnostic-metadata.h"
#include "function.h"
#include "pretty-print.h"
#include "sbitmap.h"
@@ -178,13 +177,11 @@ public:
return OPT_Wanalyzer_infinite_loop;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
/* "CWE-835: Loop with Unreachable Exit Condition ('Infinite Loop')". */
- diagnostic_metadata m;
- m.add_cwe (835);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "infinite loop");
+ ctxt.add_cwe (835);
+ return ctxt.warn ("infinite loop");
}
bool maybe_add_custom_events_for_superedge (const exploded_edge &,
diff --git a/gcc/analyzer/infinite-recursion.cc b/gcc/analyzer/infinite-recursion.cc
index 9576ff5..0fab9b7 100644
--- a/gcc/analyzer/infinite-recursion.cc
+++ b/gcc/analyzer/infinite-recursion.cc
@@ -31,7 +31,6 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-core.h"
#include "diagnostic-event-id.h"
#include "diagnostic-path.h"
-#include "diagnostic-metadata.h"
#include "function.h"
#include "pretty-print.h"
#include "sbitmap.h"
@@ -95,13 +94,11 @@ public:
return OPT_Wanalyzer_infinite_recursion;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
/* "CWE-674: Uncontrolled Recursion". */
- diagnostic_metadata m;
- m.add_cwe (674);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "infinite recursion");
+ ctxt.add_cwe (674);
+ return ctxt.warn ("infinite recursion");
}
label_text describe_final_event (const evdesc::final_event &ev) final override
diff --git a/gcc/analyzer/kf-analyzer.cc b/gcc/analyzer/kf-analyzer.cc
index 7ae598a..01e2c46 100644
--- a/gcc/analyzer/kf-analyzer.cc
+++ b/gcc/analyzer/kf-analyzer.cc
@@ -255,9 +255,9 @@ public:
return 0;
}
- bool emit (rich_location *richloc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- inform (richloc, "path");
+ ctxt.inform ("path");
return true;
}
diff --git a/gcc/analyzer/kf.cc b/gcc/analyzer/kf.cc
index 5d8e04d..a69f084 100644
--- a/gcc/analyzer/kf.cc
+++ b/gcc/analyzer/kf.cc
@@ -719,32 +719,29 @@ public:
return OPT_Wanalyzer_putenv_of_auto_var;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
auto_diagnostic_group d;
- diagnostic_metadata m;
/* SEI CERT C Coding Standard: "POS34-C. Do not call putenv() with a
pointer to an automatic variable as the argument". */
diagnostic_metadata::precanned_rule
rule ("POS34-C", "https://wiki.sei.cmu.edu/confluence/x/6NYxBQ");
- m.add_rule (rule);
+ ctxt.add_rule (rule);
bool warned;
if (m_var_decl)
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "%qE on a pointer to automatic variable %qE",
- m_fndecl, m_var_decl);
+ warned = ctxt.warn ("%qE on a pointer to automatic variable %qE",
+ m_fndecl, m_var_decl);
else
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "%qE on a pointer to an on-stack buffer",
- m_fndecl);
+ warned = ctxt.warn ("%qE on a pointer to an on-stack buffer",
+ m_fndecl);
if (warned)
{
if (m_var_decl)
inform (DECL_SOURCE_LOCATION (m_var_decl),
"%qE declared on stack here", m_var_decl);
- inform (rich_loc->get_loc (), "perhaps use %qs rather than %qE",
+ inform (ctxt.get_location (), "perhaps use %qs rather than %qE",
"setenv", m_fndecl);
}
@@ -1733,18 +1730,15 @@ public:
return OPT_Wanalyzer_undefined_behavior_strtok;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
/* CWE-476: NULL Pointer Dereference. */
- diagnostic_metadata m;
- m.add_cwe (476);
- if (warning_meta
- (rich_loc, m, get_controlling_option (),
- "calling %qD for first time with NULL as argument 1"
- " has undefined behavior",
- get_callee_fndecl ()))
+ ctxt.add_cwe (476);
+ if (ctxt.warn ("calling %qD for first time with NULL as argument 1"
+ " has undefined behavior",
+ get_callee_fndecl ()))
{
- inform (rich_loc->get_loc (),
+ inform (ctxt.get_location (),
"some implementations of %qD may crash on such input",
get_callee_fndecl ());
return true;
diff --git a/gcc/analyzer/pending-diagnostic.cc b/gcc/analyzer/pending-diagnostic.cc
index c7d3370..48d9be9 100644
--- a/gcc/analyzer/pending-diagnostic.cc
+++ b/gcc/analyzer/pending-diagnostic.cc
@@ -109,6 +109,51 @@ evdesc::event_desc::formatted_print (const char *fmt, ...) const
return result;
}
+/* class diagnostic_emission_context. */
+
+/* Get the pending_diagnostic being emitted. */
+
+const pending_diagnostic &
+diagnostic_emission_context::get_pending_diagnostic () const
+{
+ return *m_sd.m_d.get ();
+}
+
+/* Emit a warning, using the rich_location, metadata, and the
+ pending_diagnostic's option. */
+
+bool
+diagnostic_emission_context::warn (const char *gmsgid, ...)
+{
+ const pending_diagnostic &pd = get_pending_diagnostic ();
+ auto_diagnostic_group d;
+ va_list ap;
+ va_start (ap, gmsgid);
+ const bool result = emit_diagnostic_valist (DK_WARNING,
+ &m_rich_loc, &m_metadata,
+ pd.get_controlling_option (),
+ gmsgid, &ap);
+ va_end (ap);
+ return result;
+}
+
+/* Emit a note, using the rich_location and metadata (and the
+ pending_diagnostic's option). */
+
+void
+diagnostic_emission_context::inform (const char *gmsgid, ...)
+{
+ const pending_diagnostic &pd = get_pending_diagnostic ();
+ auto_diagnostic_group d;
+ va_list ap;
+ va_start (ap, gmsgid);
+ emit_diagnostic_valist (DK_NOTE,
+ &m_rich_loc, &m_metadata,
+ pd.get_controlling_option (),
+ gmsgid, &ap);
+ va_end (ap);
+}
+
/* Return true if T1 and T2 are "the same" for the purposes of
diagnostic deduplication. */
diff --git a/gcc/analyzer/pending-diagnostic.h b/gcc/analyzer/pending-diagnostic.h
index 7582b37..e393f9a 100644
--- a/gcc/analyzer/pending-diagnostic.h
+++ b/gcc/analyzer/pending-diagnostic.h
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_ANALYZER_PENDING_DIAGNOSTIC_H
#define GCC_ANALYZER_PENDING_DIAGNOSTIC_H
+#include "diagnostic-metadata.h"
#include "diagnostic-path.h"
#include "analyzer/sm.h"
@@ -144,6 +145,47 @@ struct final_event : public event_desc
} /* end of namespace evdesc */
+/* A bundle of information for use by implementations of the
+ pending_diagnostic::emit vfunc.
+
+ The rich_location will have already been populated with a
+ diagnostic_path. */
+
+class diagnostic_emission_context
+{
+public:
+ diagnostic_emission_context (const saved_diagnostic &sd,
+ rich_location &rich_loc,
+ diagnostic_metadata &metadata,
+ logger *logger)
+ : m_sd (sd),
+ m_rich_loc (rich_loc),
+ m_metadata (metadata),
+ m_logger (logger)
+ {
+ }
+
+ const pending_diagnostic &get_pending_diagnostic () const;
+
+ bool warn (const char *, ...) ATTRIBUTE_GCC_DIAG (2,3);
+ void inform (const char *, ...) ATTRIBUTE_GCC_DIAG (2,3);
+
+ location_t get_location () const { return m_rich_loc.get_loc (); }
+ logger *get_logger () const { return m_logger; }
+
+ void add_cwe (int cwe) { m_metadata.add_cwe (cwe); }
+ void add_rule (const diagnostic_metadata::rule &r)
+ {
+ m_metadata.add_rule (r);
+ }
+
+private:
+ const saved_diagnostic &m_sd;
+ rich_location &m_rich_loc;
+ diagnostic_metadata &m_metadata;
+ logger *m_logger;
+};
+
/* An abstract base class for capturing information about a diagnostic in
a form that is ready to emit at a later point (or be rejected).
Each kind of diagnostic will have a concrete subclass of
@@ -177,10 +219,9 @@ class pending_diagnostic
path being explored. By default, don't terminate the path. */
virtual bool terminate_path_p () const { return false; }
- /* Vfunc for emitting the diagnostic. The rich_location will have been
- populated with a diagnostic_path.
+ /* Vfunc for emitting the diagnostic.
Return true if a diagnostic is actually emitted. */
- virtual bool emit (rich_location *, logger *) = 0;
+ virtual bool emit (diagnostic_emission_context &) = 0;
/* Hand-coded RTTI: get an ID for the subclass. */
virtual const char *get_kind () const = 0;
@@ -361,6 +402,15 @@ class pending_diagnostic
/* Default implementation: accept this path. */
return true;
}
+
+ /* Vfunc for use in SARIF output to give pending_diagnostic subclasses
+ the opportunity to add diagnostic-specific properties to the SARIF
+ "result" object for the diagnostic.
+ This is intended for use when debugging a diagnostic. */
+ virtual void maybe_add_sarif_properties (sarif_object &/*result_obj*/) const
+ {
+ /* Default no-op implementation. */
+ }
};
/* A template to make it easier to make subclasses of pending_diagnostic.
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 420c103..2157ad2 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -40,7 +40,6 @@ along with GCC; see the file COPYING3. If not see
#include "fold-const.h"
#include "tree-pretty-print.h"
#include "diagnostic-color.h"
-#include "diagnostic-metadata.h"
#include "bitmap.h"
#include "selftest.h"
#include "analyzer/analyzer.h"
@@ -79,6 +78,7 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/checker-path.h"
#include "analyzer/feasible-graph.h"
#include "analyzer/record-layout.h"
+#include "diagnostic-format-sarif.h"
#if ENABLE_ANALYZER
@@ -512,7 +512,7 @@ public:
bool terminate_path_p () const final override { return true; }
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
switch (m_pkind)
{
@@ -520,37 +520,30 @@ public:
gcc_unreachable ();
case POISON_KIND_UNINIT:
{
- diagnostic_metadata m;
- m.add_cwe (457); /* "CWE-457: Use of Uninitialized Variable". */
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of uninitialized value %qE",
- m_expr);
+ ctxt.add_cwe (457); /* "CWE-457: Use of Uninitialized Variable". */
+ return ctxt.warn ("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_meta (rich_loc, m, get_controlling_option (),
- "use after %<free%> of %qE",
- m_expr);
+ ctxt.add_cwe (416); /* "CWE-416: Use After Free". */
+ return ctxt.warn ("use after %<free%> of %qE",
+ m_expr);
}
break;
case POISON_KIND_DELETED:
{
- diagnostic_metadata m;
- m.add_cwe (416); /* "CWE-416: Use After Free". */
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use after %<delete%> of %qE",
- m_expr);
+ ctxt.add_cwe (416); /* "CWE-416: Use After Free". */
+ return ctxt.warn ("use after %<delete%> of %qE",
+ m_expr);
}
break;
case POISON_KIND_POPPED_STACK:
{
/* TODO: which CWE? */
- return warning_at
- (rich_loc, get_controlling_option (),
- "dereferencing pointer %qE to within stale stack frame",
+ return ctxt.warn
+ ("dereferencing pointer %qE to within stale stack frame",
m_expr);
}
break;
@@ -655,10 +648,9 @@ public:
return OPT_Wanalyzer_shift_count_negative;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- return warning_at (rich_loc, get_controlling_option (),
- "shift by negative count (%qE)", m_count_cst);
+ return ctxt.warn ("shift by negative count (%qE)", m_count_cst);
}
label_text describe_final_event (const evdesc::final_event &ev) final override
@@ -702,11 +694,10 @@ public:
return OPT_Wanalyzer_shift_count_overflow;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- return warning_at (rich_loc, get_controlling_option (),
- "shift by count (%qE) >= precision of type (%qi)",
- m_count_cst, m_operand_precision);
+ return ctxt.warn ("shift by count (%qE) >= precision of type (%qi)",
+ m_count_cst, m_operand_precision);
}
label_text describe_final_event (const evdesc::final_event &ev) final override
@@ -2840,23 +2831,20 @@ public:
return OPT_Wanalyzer_write_to_const;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
auto_diagnostic_group d;
bool warned;
switch (m_reg->get_kind ())
{
default:
- warned = warning_at (rich_loc, get_controlling_option (),
- "write to %<const%> object %qE", m_decl);
+ warned = ctxt.warn ("write to %<const%> object %qE", m_decl);
break;
case RK_FUNCTION:
- warned = warning_at (rich_loc, get_controlling_option (),
- "write to function %qE", m_decl);
+ warned = ctxt.warn ("write to function %qE", m_decl);
break;
case RK_LABEL:
- warned = warning_at (rich_loc, get_controlling_option (),
- "write to label %qE", m_decl);
+ warned = ctxt.warn ("write to label %qE", m_decl);
break;
}
if (warned)
@@ -2908,10 +2896,9 @@ public:
return OPT_Wanalyzer_write_to_string_literal;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- return warning_at (rich_loc, get_controlling_option (),
- "write to string literal");
+ return ctxt.warn ("write to string literal");
/* Ideally we would show the location of the STRING_CST as well,
but it is not available at this point. */
}
@@ -3112,14 +3099,12 @@ public:
return OPT_Wanalyzer_allocation_size;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
- m.add_cwe (131);
+ ctxt.add_cwe (131);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "allocated buffer size is not a multiple"
- " of the pointee's size");
+ return ctxt.warn ("allocated buffer size is not a multiple"
+ " of the pointee's size");
}
label_text describe_final_event (const evdesc::final_event &ev) final
@@ -5970,15 +5955,14 @@ public:
return same_tree_p (m_arg, ((const float_as_size_arg &) other).m_arg);
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
- bool warned = warning_meta (rich_loc, m, get_controlling_option (),
- "use of floating-point arithmetic here might"
- " yield unexpected results");
+ bool warned = ctxt.warn ("use of floating-point arithmetic here might"
+ " yield unexpected results");
if (warned)
- inform (rich_loc->get_loc (), "only use operands of an integer type"
- " inside the size argument");
+ inform (ctxt.get_location (),
+ "only use operands of an integer type"
+ " inside the size argument");
return warned;
}
@@ -6214,37 +6198,33 @@ public:
return OPT_Wanalyzer_exposure_through_uninit_copy;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
/* CWE-200: Exposure of Sensitive Information to an Unauthorized Actor. */
- m.add_cwe (200);
+ ctxt.add_cwe (200);
enum memory_space mem_space = get_src_memory_space ();
bool warned;
switch (mem_space)
{
default:
- warned = warning_meta
- (rich_loc, m, get_controlling_option (),
- "potential exposure of sensitive information"
- " by copying uninitialized data across trust boundary");
+ warned = ctxt.warn ("potential exposure of sensitive information"
+ " by copying uninitialized data"
+ " across trust boundary");
break;
case MEMSPACE_STACK:
- warned = warning_meta
- (rich_loc, m, get_controlling_option (),
- "potential exposure of sensitive information"
- " by copying uninitialized data from stack across trust boundary");
+ warned = ctxt.warn ("potential exposure of sensitive information"
+ " by copying uninitialized data from stack"
+ " across trust boundary");
break;
case MEMSPACE_HEAP:
- warned = warning_meta
- (rich_loc, m, get_controlling_option (),
- "potential exposure of sensitive information"
- " by copying uninitialized data from heap across trust boundary");
+ warned = ctxt.warn ("potential exposure of sensitive information"
+ " by copying uninitialized data from heap"
+ " across trust boundary");
break;
}
if (warned)
{
- location_t loc = rich_loc->get_loc ();
+ const location_t loc = ctxt.get_location ();
inform_number_of_uninit_bits (loc);
complain_about_uninit_ranges (loc);
@@ -6276,6 +6256,17 @@ public:
interest->add_region_creation (m_src_region);
}
+ void
+ maybe_add_sarif_properties (sarif_object &result_obj) const final override
+ {
+ sarif_property_bag &props = result_obj.get_or_create_properties ();
+#define PROPERTY_PREFIX "gcc/-Wanalyzer-exposure-through-uninit-copy/"
+ props.set (PROPERTY_PREFIX "src_region", m_src_region->to_json ());
+ props.set (PROPERTY_PREFIX "dest_region", m_dest_region->to_json ());
+ props.set (PROPERTY_PREFIX "copied_sval", m_copied_sval->to_json ());
+#undef PROPERTY_PREFIX
+ }
+
private:
enum memory_space get_src_memory_space () const
{
diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc
index 4feb972..9b27e8f 100644
--- a/gcc/analyzer/region.cc
+++ b/gcc/analyzer/region.cc
@@ -40,7 +40,6 @@ along with GCC; see the file COPYING3. If not see
#include "fold-const.h"
#include "tree-pretty-print.h"
#include "diagnostic-color.h"
-#include "diagnostic-metadata.h"
#include "bitmap.h"
#include "analyzer/analyzer.h"
#include "analyzer/analyzer-logging.h"
diff --git a/gcc/analyzer/sm-fd.cc b/gcc/analyzer/sm-fd.cc
index 34bbd84..7f8a1d9 100644
--- a/gcc/analyzer/sm-fd.cc
+++ b/gcc/analyzer/sm-fd.cc
@@ -29,7 +29,6 @@ along with GCC; see the file COPYING3. If not see
#include "gimple.h"
#include "options.h"
#include "diagnostic-path.h"
-#include "diagnostic-metadata.h"
#include "analyzer/analyzer.h"
#include "diagnostic-event-id.h"
#include "analyzer/analyzer-logging.h"
@@ -465,19 +464,16 @@ public:
}
bool
- emit (rich_location *rich_loc, logger *) final override
+ emit (diagnostic_emission_context &ctxt) final override
{
/*CWE-775: Missing Release of File Descriptor or Handle after Effective
Lifetime
*/
- diagnostic_metadata m;
- m.add_cwe (775);
+ ctxt.add_cwe (775);
if (m_arg)
- return warning_meta (rich_loc, m, get_controlling_option (),
- "leak of file descriptor %qE", m_arg);
+ return ctxt.warn ("leak of file descriptor %qE", m_arg);
else
- return warning_meta (rich_loc, m, get_controlling_option (),
- "leak of file descriptor");
+ return ctxt.warn ("leak of file descriptor");
}
label_text
@@ -550,20 +546,18 @@ public:
}
bool
- emit (rich_location *rich_loc, logger *) final override
+ emit (diagnostic_emission_context &ctxt) final override
{
bool warned;
switch (m_fd_dir)
{
case DIRS_READ:
- warned = warning_at (rich_loc, get_controlling_option (),
- "%qE on read-only file descriptor %qE",
- m_callee_fndecl, m_arg);
+ warned = ctxt.warn ("%qE on read-only file descriptor %qE",
+ m_callee_fndecl, m_arg);
break;
case DIRS_WRITE:
- warned = warning_at (rich_loc, get_controlling_option (),
- "%qE on write-only file descriptor %qE",
- m_callee_fndecl, m_arg);
+ warned = ctxt.warn ("%qE on write-only file descriptor %qE",
+ m_callee_fndecl, m_arg);
break;
default:
gcc_unreachable ();
@@ -612,13 +606,11 @@ public:
return OPT_Wanalyzer_fd_double_close;
}
bool
- emit (rich_location *rich_loc, logger *) final override
+ emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
// CWE-1341: Multiple Releases of Same Resource or Handle
- m.add_cwe (1341);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "double %<close%> of file descriptor %qE", m_arg);
+ ctxt.add_cwe (1341);
+ return ctxt.warn ("double %<close%> of file descriptor %qE", m_arg);
}
label_text
@@ -677,12 +669,10 @@ public:
}
bool
- emit (rich_location *rich_loc, logger *) final override
+ emit (diagnostic_emission_context &ctxt) final override
{
- bool warned;
- warned = warning_at (rich_loc, get_controlling_option (),
- "%qE on closed file descriptor %qE", m_callee_fndecl,
- m_arg);
+ bool warned = ctxt.warn ("%qE on closed file descriptor %qE",
+ m_callee_fndecl, m_arg);
if (warned)
inform_filedescriptor_attribute (DIRS_READ_WRITE);
return warned;
@@ -748,12 +738,10 @@ public:
}
bool
- emit (rich_location *rich_loc, logger *) final override
+ emit (diagnostic_emission_context &ctxt) final override
{
- bool warned;
- warned = warning_at (rich_loc, get_controlling_option (),
- "%qE on possibly invalid file descriptor %qE",
- m_callee_fndecl, m_arg);
+ bool warned = ctxt.warn ("%qE on possibly invalid file descriptor %qE",
+ m_callee_fndecl, m_arg);
if (warned)
inform_filedescriptor_attribute (DIRS_READ_WRITE);
return warned;
@@ -859,14 +847,12 @@ public:
}
bool
- emit (rich_location *rich_loc, logger *) final override
+ emit (diagnostic_emission_context &ctxt) final override
{
/* CWE-666: Operation on Resource in Wrong Phase of Lifetime. */
- diagnostic_metadata m;
- m.add_cwe (666);
- return warning_at (rich_loc, get_controlling_option (),
- "%qE on file descriptor %qE in wrong phase",
- m_callee_fndecl, m_arg);
+ ctxt.add_cwe (666);
+ return ctxt.warn ("%qE on file descriptor %qE in wrong phase",
+ m_callee_fndecl, m_arg);
}
label_text
@@ -1019,25 +1005,22 @@ public:
}
bool
- emit (rich_location *rich_loc, logger *) final override
+ emit (diagnostic_emission_context &ctxt) final override
{
switch (m_expected_type)
{
default:
gcc_unreachable ();
case EXPECTED_TYPE_SOCKET:
- return warning_at (rich_loc, get_controlling_option (),
- "%qE on non-socket file descriptor %qE",
- m_callee_fndecl, m_arg);
+ return ctxt.warn ("%qE on non-socket file descriptor %qE",
+ m_callee_fndecl, m_arg);
case EXPECTED_TYPE_STREAM_SOCKET:
if (m_sm.is_datagram_socket_fd_p (m_actual_state))
- return warning_at (rich_loc, get_controlling_option (),
- "%qE on datagram socket file descriptor %qE",
- m_callee_fndecl, m_arg);
+ return ctxt.warn ("%qE on datagram socket file descriptor %qE",
+ m_callee_fndecl, m_arg);
else
- return warning_at (rich_loc, get_controlling_option (),
- "%qE on non-stream-socket file descriptor %qE",
- m_callee_fndecl, m_arg);
+ return ctxt.warn ("%qE on non-stream-socket file descriptor %qE",
+ m_callee_fndecl, m_arg);
}
}
diff --git a/gcc/analyzer/sm-file.cc b/gcc/analyzer/sm-file.cc
index 0252b39..f8e31f8 100644
--- a/gcc/analyzer/sm-file.cc
+++ b/gcc/analyzer/sm-file.cc
@@ -29,7 +29,6 @@ along with GCC; see the file COPYING3. If not see
#include "gimple.h"
#include "options.h"
#include "diagnostic-path.h"
-#include "diagnostic-metadata.h"
#include "analyzer/analyzer.h"
#include "diagnostic-event-id.h"
#include "analyzer/analyzer-logging.h"
@@ -176,14 +175,12 @@ public:
return OPT_Wanalyzer_double_fclose;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
/* CWE-1341: Multiple Releases of Same Resource or Handle. */
- m.add_cwe (1341);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "double %<fclose%> of FILE %qE",
- m_arg);
+ ctxt.add_cwe (1341);
+ return ctxt.warn ("double %<fclose%> of FILE %qE",
+ m_arg);
}
label_text describe_state_change (const evdesc::state_change &change)
@@ -224,19 +221,15 @@ public:
return OPT_Wanalyzer_file_leak;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
/* CWE-775: "Missing Release of File Descriptor or Handle after
Effective Lifetime". */
- m.add_cwe (775);
+ ctxt.add_cwe (775);
if (m_arg)
- return warning_meta (rich_loc, m, get_controlling_option (),
- "leak of FILE %qE",
- m_arg);
+ return ctxt.warn ("leak of FILE %qE", m_arg);
else
- return warning_meta (rich_loc, m, get_controlling_option (),
- "leak of FILE");
+ return ctxt.warn ("leak of FILE");
}
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 5af6544..bb78444 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -30,7 +30,6 @@ along with GCC; see the file COPYING3. If not see
#include "options.h"
#include "bitmap.h"
#include "diagnostic-path.h"
-#include "diagnostic-metadata.h"
#include "analyzer/analyzer.h"
#include "diagnostic-event-id.h"
#include "analyzer/analyzer-logging.h"
@@ -840,23 +839,20 @@ public:
return OPT_Wanalyzer_mismatching_deallocation;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
auto_diagnostic_group d;
- diagnostic_metadata m;
- m.add_cwe (762); /* CWE-762: Mismatched Memory Management Routines. */
+ ctxt.add_cwe (762); /* CWE-762: Mismatched Memory Management Routines. */
if (const deallocator *expected_dealloc
= m_expected_deallocators->maybe_get_single ())
- return warning_meta (rich_loc, m, get_controlling_option (),
- "%qE should have been deallocated with %qs"
- " but was deallocated with %qs",
- m_arg, expected_dealloc->m_name,
- m_actual_dealloc->m_name);
+ return ctxt.warn ("%qE should have been deallocated with %qs"
+ " but was deallocated with %qs",
+ m_arg, expected_dealloc->m_name,
+ m_actual_dealloc->m_name);
else
- return warning_meta (rich_loc, m, get_controlling_option (),
- "%qs called on %qE returned from a mismatched"
- " allocation function",
- m_actual_dealloc->m_name, m_arg);
+ return ctxt.warn ("%qs called on %qE returned from a mismatched"
+ " allocation function",
+ m_actual_dealloc->m_name, m_arg);
}
label_text describe_state_change (const evdesc::state_change &change)
@@ -919,13 +915,11 @@ public:
return OPT_Wanalyzer_double_free;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
auto_diagnostic_group d;
- diagnostic_metadata m;
- m.add_cwe (415); /* CWE-415: Double Free. */
- return warning_meta (rich_loc, m, get_controlling_option (),
- "double-%qs of %qE", m_funcname, m_arg);
+ ctxt.add_cwe (415); /* CWE-415: Double Free. */
+ return ctxt.warn ("double-%qs of %qE", m_funcname, m_arg);
}
label_text describe_state_change (const evdesc::state_change &change)
@@ -1015,13 +1009,11 @@ public:
return OPT_Wanalyzer_possible_null_dereference;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
/* CWE-690: Unchecked Return Value to NULL Pointer Dereference. */
- diagnostic_metadata m;
- m.add_cwe (690);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "dereference of possibly-NULL %qE", m_arg);
+ ctxt.add_cwe (690);
+ return ctxt.warn ("dereference of possibly-NULL %qE", m_arg);
}
label_text describe_final_event (const evdesc::final_event &ev) final override
@@ -1104,16 +1096,14 @@ public:
return OPT_Wanalyzer_possible_null_argument;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
/* CWE-690: Unchecked Return Value to NULL Pointer Dereference. */
auto_diagnostic_group d;
- diagnostic_metadata m;
- m.add_cwe (690);
+ ctxt.add_cwe (690);
bool warned
- = warning_meta (rich_loc, m, get_controlling_option (),
- "use of possibly-NULL %qE where non-null expected",
- m_arg);
+ = ctxt.warn ("use of possibly-NULL %qE where non-null expected",
+ m_arg);
if (warned)
inform_nonnull_attribute (m_fndecl, m_arg_idx);
return warned;
@@ -1157,13 +1147,11 @@ public:
bool terminate_path_p () const final override { return true; }
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
/* CWE-476: NULL Pointer Dereference. */
- diagnostic_metadata m;
- m.add_cwe (476);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "dereference of NULL %qE", m_arg);
+ ctxt.add_cwe (476);
+ return ctxt.warn ("dereference of NULL %qE", m_arg);
}
label_text describe_return_of_state (const evdesc::return_of_state &info)
@@ -1227,21 +1215,18 @@ public:
bool terminate_path_p () const final override { return true; }
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
/* CWE-476: NULL Pointer Dereference. */
auto_diagnostic_group d;
- diagnostic_metadata m;
- m.add_cwe (476);
+ ctxt.add_cwe (476);
bool warned;
if (zerop (m_arg))
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "use of NULL where non-null expected");
+ warned = ctxt.warn ("use of NULL where non-null expected");
else
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "use of NULL %qE where non-null expected",
- m_arg);
+ warned = ctxt.warn ("use of NULL %qE where non-null expected",
+ m_arg);
if (warned)
inform_nonnull_attribute (m_fndecl, m_arg_idx);
return warned;
@@ -1284,14 +1269,12 @@ public:
return OPT_Wanalyzer_use_after_free;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
/* CWE-416: Use After Free. */
- diagnostic_metadata m;
- m.add_cwe (416);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use after %<%s%> of %qE",
- m_deallocator->m_name, m_arg);
+ ctxt.add_cwe (416);
+ return ctxt.warn ("use after %<%s%> of %qE",
+ m_deallocator->m_name, m_arg);
}
label_text describe_state_change (const evdesc::state_change &change)
@@ -1378,17 +1361,14 @@ public:
return OPT_Wanalyzer_malloc_leak;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
/* "CWE-401: Missing Release of Memory after Effective Lifetime". */
- diagnostic_metadata m;
- m.add_cwe (401);
+ ctxt.add_cwe (401);
if (m_arg)
- return warning_meta (rich_loc, m, get_controlling_option (),
- "leak of %qE", m_arg);
+ return ctxt.warn ("leak of %qE", m_arg);
else
- return warning_meta (rich_loc, m, get_controlling_option (),
- "leak of %qs", "<unknown>");
+ return ctxt.warn ("leak of %qs", "<unknown>");
}
label_text describe_state_change (const evdesc::state_change &change)
@@ -1452,11 +1432,10 @@ public:
return OPT_Wanalyzer_free_of_non_heap;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
auto_diagnostic_group d;
- diagnostic_metadata m;
- m.add_cwe (590); /* CWE-590: Free of Memory not on the Heap. */
+ ctxt.add_cwe (590); /* CWE-590: Free of Memory not on the Heap. */
switch (get_memory_space ())
{
default:
@@ -1466,16 +1445,14 @@ public:
case MEMSPACE_CODE:
case MEMSPACE_GLOBALS:
case MEMSPACE_READONLY_DATA:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "%<%s%> of %qE which points to memory"
- " not on the heap",
- m_funcname, m_arg);
+ return ctxt.warn ("%<%s%> of %qE which points to memory"
+ " not on the heap",
+ m_funcname, m_arg);
break;
case MEMSPACE_STACK:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "%<%s%> of %qE which points to memory"
- " on the stack",
- m_funcname, m_arg);
+ return ctxt.warn ("%<%s%> of %qE which points to memory"
+ " on the stack",
+ m_funcname, m_arg);
break;
}
}
@@ -1531,7 +1508,7 @@ public:
return OPT_Wanalyzer_deref_before_check;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
/* Don't emit the warning if we can't show where the deref
and the check occur. */
@@ -1605,10 +1582,9 @@ public:
m_deref_enode->get_supernode ()->m_bb))
return false;
- return warning_at (rich_loc, get_controlling_option (),
- "check of %qE for NULL after already"
- " dereferencing it",
- m_arg);
+ return ctxt.warn ("check of %qE for NULL after already"
+ " dereferencing it",
+ m_arg);
}
label_text describe_state_change (const evdesc::state_change &change)
diff --git a/gcc/analyzer/sm-pattern-test.cc b/gcc/analyzer/sm-pattern-test.cc
index 4c88bca..cd594e0 100644
--- a/gcc/analyzer/sm-pattern-test.cc
+++ b/gcc/analyzer/sm-pattern-test.cc
@@ -31,7 +31,6 @@ along with GCC; see the file COPYING3. If not see
#include "gimple.h"
#include "tree-pretty-print.h"
#include "diagnostic-path.h"
-#include "diagnostic-metadata.h"
#include "analyzer/analyzer.h"
#include "diagnostic-event-id.h"
#include "analyzer/analyzer-logging.h"
@@ -92,11 +91,10 @@ public:
return 0;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- return warning_at (rich_loc, get_controlling_option (),
- "pattern match on %<%E %s %E%>",
- m_lhs, op_symbol_code (m_op), m_rhs);
+ return ctxt.warn ("pattern match on %<%E %s %E%>",
+ m_lhs, op_symbol_code (m_op), m_rhs);
}
private:
diff --git a/gcc/analyzer/sm-sensitive.cc b/gcc/analyzer/sm-sensitive.cc
index 0597e39..4776d64 100644
--- a/gcc/analyzer/sm-sensitive.cc
+++ b/gcc/analyzer/sm-sensitive.cc
@@ -30,7 +30,6 @@ along with GCC; see the file COPYING3. If not see
#include "gimple.h"
#include "options.h"
#include "diagnostic-path.h"
-#include "diagnostic-metadata.h"
#include "analyzer/analyzer.h"
#include "diagnostic-event-id.h"
#include "analyzer/analyzer-logging.h"
@@ -95,15 +94,12 @@ public:
return OPT_Wanalyzer_exposure_through_output_file;
}
- bool emit (rich_location *rich_loc,
- logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
/* CWE-532: Information Exposure Through Log Files */
- m.add_cwe (532);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "sensitive value %qE written to output file",
- m_arg);
+ ctxt.add_cwe (532);
+ return ctxt.warn ("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 9ebcbdb..6bca395 100644
--- a/gcc/analyzer/sm-signal.cc
+++ b/gcc/analyzer/sm-signal.cc
@@ -32,7 +32,6 @@ along with GCC; see the file COPYING3. If not see
#include "options.h"
#include "bitmap.h"
#include "diagnostic-path.h"
-#include "diagnostic-metadata.h"
#include "analyzer/analyzer.h"
#include "diagnostic-event-id.h"
#include "analyzer/analyzer-logging.h"
@@ -114,15 +113,13 @@ public:
return OPT_Wanalyzer_unsafe_call_within_signal_handler;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
auto_diagnostic_group d;
- diagnostic_metadata m;
/* CWE-479: Signal Handler Use of a Non-reentrant Function. */
- m.add_cwe (479);
- if (warning_meta (rich_loc, m, get_controlling_option (),
- "call to %qD from within signal handler",
- m_unsafe_fndecl))
+ ctxt.add_cwe (479);
+ if (ctxt.warn ("call to %qD from within signal handler",
+ m_unsafe_fndecl))
{
/* If we know a possible alternative function, add a note
suggesting the replacement. */
diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc
index dfd5f7f..d01e3f0 100644
--- a/gcc/analyzer/sm-taint.cc
+++ b/gcc/analyzer/sm-taint.cc
@@ -31,7 +31,6 @@ along with GCC; see the file COPYING3. If not see
#include "gimple.h"
#include "options.h"
#include "diagnostic-path.h"
-#include "diagnostic-metadata.h"
#include "analyzer/analyzer.h"
#include "analyzer/analyzer-logging.h"
#include "gimple-iterator.h"
@@ -211,33 +210,29 @@ public:
return OPT_Wanalyzer_tainted_array_index;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
/* CWE-129: "Improper Validation of Array Index". */
- m.add_cwe (129);
+ ctxt.add_cwe (129);
if (m_arg)
switch (m_has_bounds)
{
default:
gcc_unreachable ();
case BOUNDS_NONE:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE"
- " in array lookup without bounds checking",
- m_arg);
+ return ctxt.warn ("use of attacker-controlled value %qE"
+ " in array lookup without bounds checking",
+ m_arg);
break;
case BOUNDS_UPPER:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE"
- " in array lookup without checking for negative",
- m_arg);
+ return ctxt.warn ("use of attacker-controlled value %qE"
+ " in array lookup without checking for negative",
+ m_arg);
break;
case BOUNDS_LOWER:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE"
- " in array lookup without upper-bounds checking",
- m_arg);
+ return ctxt.warn ("use of attacker-controlled value %qE"
+ " in array lookup without upper-bounds checking",
+ m_arg);
break;
}
else
@@ -246,21 +241,18 @@ public:
default:
gcc_unreachable ();
case BOUNDS_NONE:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value"
- " in array lookup without bounds checking");
+ return ctxt.warn ("use of attacker-controlled value"
+ " in array lookup without bounds checking");
break;
case BOUNDS_UPPER:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value"
- " in array lookup without checking for"
- " negative");
+ return ctxt.warn ("use of attacker-controlled value"
+ " in array lookup without checking for"
+ " negative");
break;
case BOUNDS_LOWER:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value"
- " in array lookup without upper-bounds"
- " checking");
+ return ctxt.warn ("use of attacker-controlled value"
+ " in array lookup without upper-bounds"
+ " checking");
break;
}
}
@@ -327,33 +319,29 @@ public:
return OPT_Wanalyzer_tainted_offset;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
/* CWE-823: "Use of Out-of-range Pointer Offset". */
- m.add_cwe (823);
+ ctxt.add_cwe (823);
if (m_arg)
switch (m_has_bounds)
{
default:
gcc_unreachable ();
case BOUNDS_NONE:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE as offset"
- " without bounds checking",
- m_arg);
+ return ctxt.warn ("use of attacker-controlled value %qE as offset"
+ " without bounds checking",
+ m_arg);
break;
case BOUNDS_UPPER:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE as offset"
- " without lower-bounds checking",
- m_arg);
+ return ctxt.warn ("use of attacker-controlled value %qE as offset"
+ " without lower-bounds checking",
+ m_arg);
break;
case BOUNDS_LOWER:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE as offset"
- " without upper-bounds checking",
- m_arg);
+ return ctxt.warn ("use of attacker-controlled value %qE as offset"
+ " without upper-bounds checking",
+ m_arg);
break;
}
else
@@ -362,19 +350,16 @@ public:
default:
gcc_unreachable ();
case BOUNDS_NONE:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value as offset"
- " without bounds checking");
+ return ctxt.warn ("use of attacker-controlled value as offset"
+ " without bounds checking");
break;
case BOUNDS_UPPER:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value as offset"
- " without lower-bounds checking");
+ return ctxt.warn ("use of attacker-controlled value as offset"
+ " without lower-bounds checking");
break;
case BOUNDS_LOWER:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value as offset"
- " without upper-bounds checking");
+ return ctxt.warn ("use of attacker-controlled value as offset"
+ " without upper-bounds checking");
break;
}
}
@@ -437,33 +422,29 @@ public:
return OPT_Wanalyzer_tainted_size;
}
- bool emit (rich_location *rich_loc, logger *) override
+ bool emit (diagnostic_emission_context &ctxt) override
{
/* "CWE-129: Improper Validation of Array Index". */
- diagnostic_metadata m;
- m.add_cwe (129);
+ ctxt.add_cwe (129);
if (m_arg)
switch (m_has_bounds)
{
default:
gcc_unreachable ();
case BOUNDS_NONE:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE as size"
- " without bounds checking",
- m_arg);
+ return ctxt.warn ("use of attacker-controlled value %qE as size"
+ " without bounds checking",
+ m_arg);
break;
case BOUNDS_UPPER:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE as size"
- " without lower-bounds checking",
- m_arg);
+ return ctxt.warn ("use of attacker-controlled value %qE as size"
+ " without lower-bounds checking",
+ m_arg);
break;
case BOUNDS_LOWER:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE as size"
- " without upper-bounds checking",
- m_arg);
+ return ctxt.warn ("use of attacker-controlled value %qE as size"
+ " without upper-bounds checking",
+ m_arg);
break;
}
else
@@ -472,19 +453,16 @@ public:
default:
gcc_unreachable ();
case BOUNDS_NONE:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value as size"
- " without bounds checking");
+ return ctxt.warn ("use of attacker-controlled value as size"
+ " without bounds checking");
break;
case BOUNDS_UPPER:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value as size"
- " without lower-bounds checking");
+ return ctxt.warn ("use of attacker-controlled value as size"
+ " without lower-bounds checking");
break;
case BOUNDS_LOWER:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value as size"
- " without upper-bounds checking");
+ return ctxt.warn ("use of attacker-controlled value as size"
+ " without upper-bounds checking");
break;
}
}
@@ -547,9 +525,9 @@ public:
return "tainted_access_attrib_size";
}
- bool emit (rich_location *rich_loc, logger *logger) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- bool warned = tainted_size::emit (rich_loc, logger);
+ bool warned = tainted_size::emit (ctxt);
if (warned)
{
inform (DECL_SOURCE_LOCATION (m_callee_fndecl),
@@ -583,20 +561,17 @@ public:
return OPT_Wanalyzer_tainted_divisor;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
/* CWE-369: "Divide By Zero". */
- m.add_cwe (369);
+ ctxt.add_cwe (369);
if (m_arg)
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE as divisor"
- " without checking for zero",
- m_arg);
+ return ctxt.warn ("use of attacker-controlled value %qE as divisor"
+ " without checking for zero",
+ m_arg);
else
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value as divisor"
- " without checking for zero");
+ return ctxt.warn ("use of attacker-controlled value as divisor"
+ " without checking for zero");
}
label_text describe_final_event (const evdesc::final_event &ev) final override
@@ -645,11 +620,10 @@ public:
return OPT_Wanalyzer_tainted_allocation_size;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
/* "CWE-789: Memory Allocation with Excessive Size Value". */
- m.add_cwe (789);
+ ctxt.add_cwe (789);
bool warned;
if (m_arg)
@@ -658,24 +632,21 @@ public:
default:
gcc_unreachable ();
case BOUNDS_NONE:
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE as"
- " allocation size without bounds checking",
- m_arg);
+ warned = ctxt.warn ("use of attacker-controlled value %qE as"
+ " allocation size without bounds checking",
+ m_arg);
break;
case BOUNDS_UPPER:
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE as"
- " allocation size without"
- " lower-bounds checking",
- m_arg);
+ warned = ctxt.warn ("use of attacker-controlled value %qE as"
+ " allocation size without"
+ " lower-bounds checking",
+ m_arg);
break;
case BOUNDS_LOWER:
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE as"
- " allocation size without"
- " upper-bounds checking",
- m_arg);
+ warned = ctxt.warn ("use of attacker-controlled value %qE as"
+ " allocation size without"
+ " upper-bounds checking",
+ m_arg);
break;
}
else
@@ -684,27 +655,24 @@ public:
default:
gcc_unreachable ();
case BOUNDS_NONE:
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value as"
- " allocation size without bounds"
- " checking");
+ warned = ctxt.warn ("use of attacker-controlled value as"
+ " allocation size without bounds"
+ " checking");
break;
case BOUNDS_UPPER:
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value as"
- " allocation size without"
- " lower-bounds checking");
+ warned = ctxt.warn ("use of attacker-controlled value as"
+ " allocation size without"
+ " lower-bounds checking");
break;
case BOUNDS_LOWER:
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value as"
- " allocation size without"
- " upper-bounds checking");
+ warned = ctxt.warn ("use of attacker-controlled value as"
+ " allocation size without"
+ " upper-bounds checking");
break;
}
if (warned)
{
- location_t loc = rich_loc->get_loc ();
+ const location_t loc = ctxt.get_location ();
switch (m_mem_space)
{
default:
@@ -800,15 +768,13 @@ public:
return OPT_Wanalyzer_tainted_assertion;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
/* "CWE-617: Reachable Assertion". */
- m.add_cwe (617);
+ ctxt.add_cwe (617);
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacked-controlled value in"
- " condition for assertion");
+ return ctxt.warn ("use of attacked-controlled value in"
+ " condition for assertion");
}
location_t fixup_location (location_t loc,
diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc
index 6025085..be1802e 100644
--- a/gcc/analyzer/store.cc
+++ b/gcc/analyzer/store.cc
@@ -38,7 +38,6 @@ along with GCC; see the file COPYING3. If not see
#include "fold-const.h"
#include "tree-pretty-print.h"
#include "diagnostic-color.h"
-#include "diagnostic-metadata.h"
#include "bitmap.h"
#include "selftest.h"
#include "analyzer/analyzer.h"
diff --git a/gcc/analyzer/varargs.cc b/gcc/analyzer/varargs.cc
index f79b2a7..7cdfb20 100644
--- a/gcc/analyzer/varargs.cc
+++ b/gcc/analyzer/varargs.cc
@@ -41,7 +41,6 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/supergraph.h"
#include "analyzer/diagnostic-manager.h"
#include "analyzer/exploded-graph.h"
-#include "diagnostic-metadata.h"
#include "analyzer/call-details.h"
#if ENABLE_ANALYZER
@@ -403,11 +402,9 @@ public:
&& 0 == strcmp (m_usage_fnname, other.m_usage_fnname));
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- auto_diagnostic_group d;
- return warning_at (rich_loc, get_controlling_option (),
- "%qs after %qs", m_usage_fnname, "va_end");
+ return ctxt.warn ("%qs after %qs", m_usage_fnname, "va_end");
}
const char *get_kind () const final override
@@ -478,11 +475,9 @@ public:
return va_list_sm_diagnostic::subclass_equal_p (other);
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- auto_diagnostic_group d;
- return warning_at (rich_loc, get_controlling_option (),
- "missing call to %qs", "va_end");
+ return ctxt.warn ("missing call to %qs", "va_end");
}
const char *get_kind () const final override { return "va_list_leak"; }
@@ -892,18 +887,15 @@ public:
return OPT_Wanalyzer_va_arg_type_mismatch;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- auto_diagnostic_group d;
- diagnostic_metadata m;
/* "CWE-686: Function Call With Incorrect Argument Type". */
- m.add_cwe (686);
+ ctxt.add_cwe (686);
bool warned
- = warning_meta (rich_loc, m, get_controlling_option (),
- "%<va_arg%> expected %qT but received %qT"
- " for variadic argument %i of %qE",
- m_expected_type, m_actual_type,
- get_variadic_index_for_diagnostic (), m_va_list_tree);
+ = ctxt.warn ("%<va_arg%> expected %qT but received %qT"
+ " for variadic argument %i of %qE",
+ m_expected_type, m_actual_type,
+ get_variadic_index_for_diagnostic (), m_va_list_tree);
return warned;
}
@@ -942,15 +934,12 @@ public:
return OPT_Wanalyzer_va_list_exhausted;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- auto_diagnostic_group d;
- diagnostic_metadata m;
/* CWE-685: Function Call With Incorrect Number of Arguments. */
- m.add_cwe (685);
- bool warned = warning_meta (rich_loc, m, get_controlling_option (),
- "%qE has no more arguments (%i consumed)",
- m_va_list_tree, get_num_consumed ());
+ ctxt.add_cwe (685);
+ bool warned = ctxt.warn ("%qE has no more arguments (%i consumed)",
+ m_va_list_tree, get_num_consumed ());
return warned;
}
diff --git a/gcc/diagnostic-core.h b/gcc/diagnostic-core.h
index 04eba3d..965c9e9 100644
--- a/gcc/diagnostic-core.h
+++ b/gcc/diagnostic-core.h
@@ -123,6 +123,12 @@ 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 *,
+ int,
+ const char *,
+ va_list *) ATTRIBUTE_GCC_DIAG (5,0);
extern bool seen_error (void);
#ifdef BUFSIZ
diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc
index 1bb7286..6777592 100644
--- a/gcc/diagnostic-format-sarif.cc
+++ b/gcc/diagnostic-format-sarif.cc
@@ -569,16 +569,20 @@ sarif_builder::make_result_object (diagnostic_context *context,
free (rule_id);
}
- /* "taxa" property (SARIF v2.1.0 section 3.27.8). */
if (diagnostic->metadata)
- if (int cwe_id = diagnostic->metadata->get_cwe ())
- {
- json::array *taxa_arr = new json::array ();
- json::object *cwe_id_obj
- = make_reporting_descriptor_reference_object_for_cwe_id (cwe_id);
- taxa_arr->append (cwe_id_obj);
- result_obj->set ("taxa", taxa_arr);
- }
+ {
+ /* "taxa" property (SARIF v2.1.0 section 3.27.8). */
+ if (int cwe_id = diagnostic->metadata->get_cwe ())
+ {
+ json::array *taxa_arr = new json::array ();
+ json::object *cwe_id_obj
+ = make_reporting_descriptor_reference_object_for_cwe_id (cwe_id);
+ taxa_arr->append (cwe_id_obj);
+ result_obj->set ("taxa", taxa_arr);
+ }
+
+ diagnostic->metadata->maybe_add_sarif_properties (*result_obj);
+ }
/* "level" property (SARIF v2.1.0 section 3.27.10). */
if (const char *sarif_level = maybe_get_sarif_level (diagnostic->kind))
diff --git a/gcc/diagnostic-metadata.h b/gcc/diagnostic-metadata.h
index 8e06c89..1af80fd 100644
--- a/gcc/diagnostic-metadata.h
+++ b/gcc/diagnostic-metadata.h
@@ -21,6 +21,8 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_DIAGNOSTIC_METADATA_H
#define GCC_DIAGNOSTIC_METADATA_H
+class sarif_object;
+
/* A bundle of additional metadata that can be associated with a
diagnostic.
@@ -63,6 +65,14 @@ class diagnostic_metadata
};
diagnostic_metadata () : m_cwe (0) {}
+ virtual ~diagnostic_metadata () {}
+
+ /* Hook for SARIF output to allow for adding diagnostic-specific
+ properties to the result object's property bag. */
+ virtual void
+ maybe_add_sarif_properties (sarif_object &/*result_obj*/) const
+ {
+ }
void add_cwe (int cwe) { m_cwe = cwe; }
int get_cwe () const { return m_cwe; }
diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index 4f66fa6..2e3d37b 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -1834,6 +1834,18 @@ emit_diagnostic_valist (diagnostic_t kind, location_t location, int opt,
return diagnostic_impl (&richloc, NULL, opt, gmsgid, ap, kind);
}
+/* As above, but with rich_location and metadata. */
+
+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
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-accept.c b/gcc/testsuite/gcc.dg/analyzer/fd-accept.c
index cce9555..d07ab15 100644
--- a/gcc/testsuite/gcc.dg/analyzer/fd-accept.c
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-accept.c
@@ -65,7 +65,7 @@ int test_accept_on_accept (int fd_a)
if (fd_b == -1)
return -1;
- int fd_c = accept (fd_b, NULL, 0); /* { dg-warning "'accept' on file descriptor 'fd_b' in wrong phase \\\[-Wanalyzer-fd-phase-mismatch\\\]" "warning" } */
+ int fd_c = accept (fd_b, NULL, 0); /* { dg-warning "'accept' on file descriptor 'fd_b' in wrong phase \\\[CWE-666\\\] \\\[-Wanalyzer-fd-phase-mismatch\\\]" "warning" } */
/* { dg-message "'accept' expects a listening stream socket file descriptor but 'fd_b' is connected" "final event" { target *-*-* } .-1 } */
return fd_b;
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-bind.c b/gcc/testsuite/gcc.dg/analyzer/fd-bind.c
index 2a5cee5..2f69841 100644
--- a/gcc/testsuite/gcc.dg/analyzer/fd-bind.c
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-bind.c
@@ -35,7 +35,7 @@ void test_double_bind (int fd, const char *sockname)
addr.sun_family = AF_UNIX;
strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
bind (fd, (struct sockaddr *)&addr, sizeof (addr));
- bind (fd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-warning "'bind' on file descriptor 'fd' in wrong phase \\\[-Wanalyzer-fd-phase-mismatch\\\]" "warning" } */
+ bind (fd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-warning "'bind' on file descriptor 'fd' in wrong phase \\\[CWE-666\\\] \\\[-Wanalyzer-fd-phase-mismatch\\\]" "warning" } */
/* { dg-message "'bind' expects a new socket file descriptor but 'fd' has already been bound" "final event" { target *-*-* } .-1 } */
}
@@ -71,7 +71,7 @@ void test_bind_after_accept (int fd, const char *sockname)
memset (&addr, 0, sizeof (addr));
addr.sun_family = AF_UNIX;
strncpy (addr.sun_path, sockname, sizeof(addr.sun_path) - 1);
- bind (afd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-warning "'bind' on file descriptor 'afd' in wrong phase \\\[-Wanalyzer-fd-phase-mismatch\\\]" "warning" } */
+ bind (afd, (struct sockaddr *)&addr, sizeof (addr)); /* { dg-warning "'bind' on file descriptor 'afd' in wrong phase \\\[CWE-666\\\] \\\[-Wanalyzer-fd-phase-mismatch\\\]" "warning" } */
/* { dg-message "'bind' expects a new socket file descriptor but 'afd' is already connected" "final event" { target *-*-* } .-1 } */
close (afd);
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-socket-misuse.c b/gcc/testsuite/gcc.dg/analyzer/fd-socket-misuse.c
index 87e8967..9149486 100644
--- a/gcc/testsuite/gcc.dg/analyzer/fd-socket-misuse.c
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-socket-misuse.c
@@ -18,7 +18,7 @@ void test_read_on_new_socket (void *buf)
int fd = socket (AF_UNIX, SOCK_STREAM, 0); /* { dg-message "stream socket created here" } */
if (fd == -1)
return;
- read (fd, buf, 1); /* { dg-warning "'read' on file descriptor 'fd' in wrong phase \\\[-Wanalyzer-fd-phase-mismatch\\\]" "warning" } */
+ read (fd, buf, 1); /* { dg-warning "'read' on file descriptor 'fd' in wrong phase \\\[CWE-666\\\] \\\[-Wanalyzer-fd-phase-mismatch\\\]" "warning" } */
/* { dg-message "'read' expects a stream socket to be connected via 'accept' but 'fd' has not yet been bound" "final event" { target *-*-* } .-1 } */
close (fd);
}
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.c b/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.c
index a364c8a..b5814dd 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.c
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_cpython_plugin.c
@@ -310,18 +310,16 @@ public:
}
bool
- emit (rich_location *rich_loc, logger *) final override
+ emit (diagnostic_emission_context &ctxt) final override
{
- diagnostic_metadata m;
bool warned;
// just assuming constants for now
auto actual_refcnt
= m_actual_refcnt->dyn_cast_constant_svalue ()->get_constant ();
auto ob_refcnt = m_ob_refcnt->dyn_cast_constant_svalue ()->get_constant ();
- warned = warning_meta (rich_loc, m, get_controlling_option (),
- "expected %qE to have "
- "reference count: %qE but ob_refcnt field is: %qE",
- m_reg_tree, actual_refcnt, ob_refcnt);
+ warned = ctxt.warn ("expected %qE to have "
+ "reference count: %qE but ob_refcnt field is: %qE",
+ m_reg_tree, actual_refcnt, ob_refcnt);
// location_t loc = rich_loc->get_loc ();
// foo (loc);
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c
index e0fc9cd..6ea6c03 100644
--- a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c
@@ -155,10 +155,9 @@ class double_save_thread : public gil_diagnostic
return m_call == sub_other.m_call;
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- return warning_at (rich_loc, get_controlling_option (),
- "nested usage of %qs", "Py_BEGIN_ALLOW_THREADS");
+ return ctxt.warn ("nested usage of %qs", "Py_BEGIN_ALLOW_THREADS");
}
label_text describe_final_event (const evdesc::final_event &ev) final override
@@ -194,19 +193,16 @@ class fncall_without_gil : public gil_diagnostic
&& m_arg_idx == sub_other.m_arg_idx);
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- auto_diagnostic_group d;
if (m_callee_fndecl)
- return warning_at (rich_loc, get_controlling_option (),
- "use of PyObject as argument %i of %qE"
- " without the GIL",
- m_arg_idx + 1, m_callee_fndecl);
+ return ctxt.warn ("use of PyObject as argument %i of %qE"
+ " without the GIL",
+ m_arg_idx + 1, m_callee_fndecl);
else
- return warning_at (rich_loc, get_controlling_option (),
- "use of PyObject as argument %i of call"
- " without the GIL",
- m_arg_idx + 1, m_callee_fndecl);
+ return ctxt.warn ("use of PyObject as argument %i of call"
+ " without the GIL",
+ m_arg_idx + 1, m_callee_fndecl);
}
label_text describe_final_event (const evdesc::final_event &ev) final override
@@ -245,11 +241,9 @@ class pyobject_usage_without_gil : public gil_diagnostic
((const pyobject_usage_without_gil&)base_other).m_expr);
}
- bool emit (rich_location *rich_loc, logger *) final override
+ bool emit (diagnostic_emission_context &ctxt) final override
{
- auto_diagnostic_group d;
- return warning_at (rich_loc, get_controlling_option (),
- "use of PyObject %qE without the GIL", m_expr);
+ return ctxt.warn ("use of PyObject %qE without the GIL", m_expr);
}
label_text describe_final_event (const evdesc::final_event &ev) final override