diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h index cf32d4b85b1..3115f878573 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 583b5ab36a0..cc43ecc5468 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 9480f037eaa..c5ae2dcb13a 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 a6755f2193f..ecd57376b54 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 27ab9ed068e..b6d6f087732 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 b4e855fcf24..1f930a21eb3 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 771d698a60b..c47ce1c8908 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 9576ff5f58d..0fab9b702a8 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 7ae598a8912..01e2c46d5ad 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 5d8e04d9726..a69f084bbf3 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 c7d337033f1..48d9be9ba2d 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 7582b37efe7..e393f9ae24e 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 420c10380a4..2157ad2578b 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 % of %qE", - m_expr); + ctxt.add_cwe (416); /* "CWE-416: Use After Free". */ + return ctxt.warn ("use after % 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 % of %qE", - m_expr); + ctxt.add_cwe (416); /* "CWE-416: Use After Free". */ + return ctxt.warn ("use after % 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 % object %qE", m_decl); + warned = ctxt.warn ("write to % 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 4feb9721ae7..9b27e8febcc 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 34bbd84f6e7..7f8a1d9b949 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 % of file descriptor %qE", m_arg); + ctxt.add_cwe (1341); + return ctxt.warn ("double % 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 0252b3922d4..f8e31f873a5 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 % of FILE %qE", - m_arg); + ctxt.add_cwe (1341); + return ctxt.warn ("double % 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 5af654414b4..bb784448397 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", ""); + return ctxt.warn ("leak of %qs", ""); } 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 4c88bcaeb2b..cd594e09c00 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 0597e390b3b..4776d6465bb 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 9ebcbdbc8e0..6bca395ac5c 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 dfd5f7fa5d2..d01e3f03951 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 602508598cc..be1802e1e5a 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 f79b2a7d7b5..7cdfb203a33 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 (), - "% 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 ("% 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 04eba3d140e..965c9e986ab 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 1bb728654e6..67775929f85 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 8e06c89d74a..1af80fd9be7 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 4f66fa6acaa..2e3d37b04cc 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 cce95555421..d07ab154d0f 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 2a5cee58230..2f69841bfd2 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 87e8967ff21..914948644bb 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 a364c8a678b..b5814dd709e 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 e0fc9cd3e47..6ea6c03e1d5 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