LCOV - code coverage report
Current view: top level - gcc/analyzer - diagnostic-manager.h Coverage Total Hit
Test: gcc.info Lines: 100.0 % 14 14
Test Date: 2026-02-28 14:20:25 Functions: - 0 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Classes for saving, deduplicating, and emitting analyzer diagnostics.
       2              :    Copyright (C) 2019-2026 Free Software Foundation, Inc.
       3              :    Contributed by David Malcolm <dmalcolm@redhat.com>.
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it
       8              : under the terms of the GNU General Public License as published by
       9              : the Free Software Foundation; either version 3, or (at your option)
      10              : any later version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but
      13              : WITHOUT ANY WARRANTY; without even the implied warranty of
      14              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15              : General Public License for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : #ifndef GCC_ANALYZER_DIAGNOSTIC_MANAGER_H
      22              : #define GCC_ANALYZER_DIAGNOSTIC_MANAGER_H
      23              : 
      24              : #include "analyzer/supergraph.h"
      25              : #include "analyzer/event-loc-info.h"
      26              : 
      27              : namespace ana {
      28              : 
      29              : class epath_finder;
      30              : 
      31              : /* A bundle of information capturing where a pending_diagnostic should
      32              :    be emitted.  */
      33              : 
      34        17774 : struct pending_location
      35              : {
      36              : public:
      37         1256 :   class fixer_for_epath
      38              :   {
      39              :   public:
      40              :     virtual ~fixer_for_epath () = default;
      41              : 
      42              :     virtual void
      43              :     fixup_for_epath (const exploded_path &epath,
      44              :                      pending_location &ploc) const = 0;
      45              :   };
      46              : 
      47              :   pending_location ();
      48              :   pending_location (exploded_node *enode);
      49              :   pending_location (exploded_node *enode,
      50              :                     location_t loc);
      51              : 
      52          147 :   location_t get_location () const
      53              :   {
      54          147 :     return m_event_loc_info.m_loc;
      55              :   }
      56              : 
      57              :   std::unique_ptr<json::object> to_json () const;
      58              : 
      59              :   /* The enode with which a diagnostic is to be associated,
      60              :      for tracking feasibility.  */
      61              :   exploded_node *m_enode;
      62              : 
      63              :   /* Information to use for the location of the warning,
      64              :      and for the location of the "final warning" in the path.  */
      65              :   event_loc_info m_event_loc_info;
      66              : 
      67              :   /* Optional hook for use when eventually emitting the diagnostic
      68              :      for fixing up m_event_loc_info based on the specific epath.  */
      69              :   std::unique_ptr<fixer_for_epath> m_fixer_for_epath;
      70              : };
      71              : 
      72              : extern std::unique_ptr<pending_location::fixer_for_epath>
      73              : make_ploc_fixer_for_epath_for_leak_diagnostic (const exploded_graph &eg,
      74              :                                                tree var);
      75              : 
      76              : /* A to-be-emitted diagnostic stored within diagnostic_manager.  */
      77              : 
      78              : class saved_diagnostic
      79              : {
      80              : public:
      81              :   saved_diagnostic (const state_machine *sm,
      82              :                     pending_location &&ploc,
      83              :                     tree var, const svalue *sval,
      84              :                     state_machine::state_t state,
      85              :                     std::unique_ptr<pending_diagnostic> d,
      86              :                     unsigned idx);
      87              : 
      88              :   bool operator== (const saved_diagnostic &other) const;
      89              : 
      90              :   void add_note (std::unique_ptr<pending_note> pn);
      91              :   void add_event (std::unique_ptr<checker_event> event);
      92              : 
      93              :   std::unique_ptr<json::object> to_json () const;
      94              : 
      95              :   void dump_dot_id (pretty_printer *pp) const;
      96              :   void dump_as_dot_node (pretty_printer *pp) const;
      97              : 
      98         3995 :   const feasibility_problem *get_feasibility_problem () const
      99              :   {
     100         3995 :     return m_problem.get ();
     101              :   }
     102              : 
     103              :   bool calc_best_epath (epath_finder *pf);
     104        10088 :   const exploded_path *get_best_epath () const { return m_best_epath.get (); }
     105              :   unsigned get_epath_length () const;
     106              : 
     107              :   void add_duplicate (saved_diagnostic *other);
     108        10650 :   unsigned get_num_dupes () const { return m_duplicates.length (); }
     109              : 
     110         4005 :   unsigned get_index () const { return m_idx; }
     111              : 
     112              :   bool supercedes_p (const saved_diagnostic &other) const;
     113              : 
     114              :   void add_any_saved_events (checker_path &dst_path);
     115              : 
     116              :   void emit_any_notes () const;
     117              : 
     118              :   void
     119              :   maybe_add_sarif_properties (diagnostics::sarif_object &result_obj) const;
     120              : 
     121              :   const supernode *get_supernode () const;
     122              : 
     123              :   //private:
     124              :   const state_machine *m_sm;
     125              :   pending_location m_ploc;
     126              :   tree m_var;
     127              :   const svalue *m_sval;
     128              :   state_machine::state_t m_state;
     129              :   std::unique_ptr<pending_diagnostic> m_d;
     130              :   const exploded_edge *m_trailing_eedge;
     131              : 
     132              : private:
     133              :   DISABLE_COPY_AND_ASSIGN (saved_diagnostic);
     134              : 
     135              :   unsigned m_idx;
     136              :   std::unique_ptr<exploded_path> m_best_epath;
     137              :   std::unique_ptr<feasibility_problem> m_problem;
     138              : 
     139              :   auto_vec<const saved_diagnostic *> m_duplicates;
     140              :   auto_delete_vec <pending_note> m_notes;
     141              : 
     142              :   /* Optionally: additional context-dependent events to be emitted
     143              :      immediately before the warning_event, giving more details of what
     144              :      operation was being simulated when a diagnostic was saved
     145              :      e.g. "looking for null terminator in param 2 of 'foo'".  */
     146              :   auto_delete_vec <checker_event> m_saved_events;
     147              : };
     148              : 
     149              : class path_builder;
     150              : 
     151              : /* A class with responsibility for saving pending diagnostics, so that
     152              :    they can be emitted after the exploded_graph is complete.
     153              :    This lets us de-duplicate diagnostics, and find the shortest path
     154              :    for each similar diagnostic, potentially using edges that might
     155              :    not have been found when each diagnostic was first saved.
     156              : 
     157              :    This also lets us compute shortest_paths once, rather than
     158              :    per-diagnostic.  */
     159              : 
     160         3377 : class diagnostic_manager : public log_user
     161              : {
     162              : public:
     163              :   diagnostic_manager (logger *logger, engine *eng, int verbosity);
     164              : 
     165              :   engine *get_engine () const { return m_eng; }
     166              : 
     167              :   std::unique_ptr<json::object> to_json () const;
     168              : 
     169              :   bool add_diagnostic (const state_machine *sm,
     170              :                        pending_location &&ploc,
     171              :                        tree var,
     172              :                        const svalue *sval,
     173              :                        state_machine::state_t state,
     174              :                        std::unique_ptr<pending_diagnostic> d);
     175              : 
     176              :   bool add_diagnostic (pending_location &&ploc,
     177              :                        std::unique_ptr<pending_diagnostic> d);
     178              : 
     179              :   void add_note (std::unique_ptr<pending_note> pn);
     180              :   void add_event (std::unique_ptr<checker_event> event);
     181              : 
     182              :   void emit_saved_diagnostics (const exploded_graph &eg);
     183              : 
     184              :   void emit_saved_diagnostic (const exploded_graph &eg,
     185              :                               saved_diagnostic &sd);
     186              : 
     187           40 :   unsigned get_num_diagnostics () const
     188              :   {
     189           44 :     return m_saved_diagnostics.length ();
     190              :   }
     191            8 :   saved_diagnostic *get_saved_diagnostic (unsigned idx)
     192              :   {
     193            8 :     return m_saved_diagnostics[idx];
     194              :   }
     195              :   const saved_diagnostic *get_saved_diagnostic (unsigned idx) const
     196              :   {
     197              :     return m_saved_diagnostics[idx];
     198              :   }
     199              : 
     200              : private:
     201              :   const diagnostics::logical_locations::manager &
     202              :   get_logical_location_manager () const;
     203              : 
     204              :   void build_emission_path (const path_builder &pb,
     205              :                             const exploded_path &epath,
     206              :                             checker_path *emission_path) const;
     207              : 
     208              :   void add_event_on_final_node (const path_builder &pb,
     209              :                                 const exploded_node *final_enode,
     210              :                                 checker_path *emission_path,
     211              :                                 interesting_t *interest) const;
     212              : 
     213              :   void add_events_for_eedge (const path_builder &pb,
     214              :                              const exploded_edge &eedge,
     215              :                              checker_path *emission_path,
     216              :                              interesting_t *interest) const;
     217              : 
     218              :   bool significant_edge_p (const path_builder &pb,
     219              :                            const exploded_edge &eedge) const;
     220              : 
     221              :   void prune_path (checker_path *path,
     222              :                    const state_machine *sm,
     223              :                    const svalue *sval,
     224              :                    state_machine::state_t state) const;
     225              : 
     226              :   void prune_for_sm_diagnostic (checker_path *path,
     227              :                                 const state_machine *sm,
     228              :                                 tree var,
     229              :                                 state_machine::state_t state) const;
     230              :   void prune_for_sm_diagnostic (checker_path *path,
     231              :                                 const state_machine *sm,
     232              :                                 const svalue *sval,
     233              :                                 state_machine::state_t state) const;
     234              :   void update_for_unsuitable_sm_exprs (tree *expr) const;
     235              :   void prune_interproc_events (checker_path *path) const;
     236              :   void prune_system_headers (checker_path *path) const;
     237              :   void consolidate_conditions (checker_path *path) const;
     238              :   void consolidate_unwind_events (checker_path *path) const;
     239              :   void finish_pruning (checker_path *path) const;
     240              : 
     241              :   engine *m_eng;
     242              :   auto_delete_vec<saved_diagnostic> m_saved_diagnostics;
     243              :   const int m_verbosity;
     244              :   int m_num_disabled_diagnostics;
     245              : };
     246              : 
     247              : } // namespace ana
     248              : 
     249              : #endif /* GCC_ANALYZER_DIAGNOSTIC_MANAGER_H */
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.