LCOV - code coverage report
Current view: top level - gcc/analyzer - common.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.5 % 86 83
Test Date: 2026-05-30 15:37:04 Functions: 92.3 % 26 24
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Base header for the analyzer, plus utility functions.
       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_COMMON_H
      22              : #define GCC_ANALYZER_COMMON_H
      23              : 
      24              : #include "config.h"
      25              : #define INCLUDE_ALGORITHM
      26              : #define INCLUDE_LIST
      27              : #define INCLUDE_MAP
      28              : #define INCLUDE_SET
      29              : #define INCLUDE_STRING
      30              : #define INCLUDE_VECTOR
      31              : #include "system.h"
      32              : #include "coretypes.h"
      33              : #include "tree.h"
      34              : #include "function.h"
      35              : #include "basic-block.h"
      36              : #include "gimple.h"
      37              : #include "options.h"
      38              : #include "bitmap.h"
      39              : #include "diagnostic-core.h"
      40              : #include "diagnostics/paths.h"
      41              : #include "rich-location.h"
      42              : #include "function.h"
      43              : #include "json.h"
      44              : #include "tristate.h"
      45              : #include "value-range.h"
      46              : 
      47              : class graphviz_out;
      48              : 
      49              : namespace ana {
      50              : 
      51              : /* Forward decls of common types, with indentation to show inheritance.  */
      52              : 
      53              : class supergraph;
      54              : class supernode;
      55              : class superedge;
      56              : 
      57              : class svalue;
      58              :   class region_svalue;
      59              :   class constant_svalue;
      60              :   class unknown_svalue;
      61              :   class poisoned_svalue;
      62              :   class setjmp_svalue;
      63              :   class initial_svalue;
      64              :   class unaryop_svalue;
      65              :   class binop_svalue;
      66              :   class sub_svalue;
      67              :   class repeated_svalue;
      68              :   class bits_within_svalue;
      69              :   class unmergeable_svalue;
      70              :   class placeholder_svalue;
      71              :   class widening_svalue;
      72              :   class compound_svalue;
      73              :   class conjured_svalue;
      74              :   class asm_output_svalue;
      75              :   class const_fn_result_svalue;
      76              : typedef hash_set<const svalue *> svalue_set;
      77              : class region;
      78              :   class frame_region;
      79              :   class function_region;
      80              :   class label_region;
      81              :   class decl_region;
      82              :   class symbolic_region;
      83              :   class element_region;
      84              :   class offset_region;
      85              :   class sized_region;
      86              :   class cast_region;
      87              :   class field_region;
      88              :   class string_region;
      89              :   class bit_range_region;
      90              :   class var_arg_region;
      91              : class region_model_manager;
      92              : class conjured_purge;
      93              : struct model_merger;
      94              : class store_manager;
      95              : class store;
      96              : class region_model;
      97              : class region_model_context;
      98              :   class impl_region_model_context;
      99              : class call_details;
     100              : class rejected_constraint;
     101              : class constraint_manager;
     102              : class equiv_class;
     103              : class reachable_regions;
     104              : class bounded_ranges;
     105              : class bounded_ranges_manager;
     106              : 
     107              : struct pending_location;
     108              : class pending_diagnostic;
     109              : class pending_note;
     110              : class saved_diagnostic;
     111              : struct event_loc_info;
     112              : class checker_event;
     113              :   class state_change_event;
     114              :   class warning_event;
     115              : class checker_path;
     116              : class extrinsic_state;
     117              : class sm_state_map;
     118              : class program_point;
     119              : class program_state;
     120              : class exploded_graph;
     121              : class exploded_node;
     122              : class exploded_edge;
     123              : class feasibility_problem;
     124              : class feasibility_state;
     125              : class exploded_cluster;
     126              : class exploded_path;
     127              : class analysis_plan;
     128              : class state_purge_map;
     129              : class state_purge_per_ssa_name;
     130              : class state_purge_per_decl;
     131              : class state_change;
     132              : class rewind_info_t;
     133              : 
     134              : class engine;
     135              : class state_machine;
     136              : class logger;
     137              : class visitor;
     138              : class known_function_manager;
     139              : class call_summary;
     140              : class call_summary_replay;
     141              : struct per_function_data;
     142              : struct interesting_t;
     143              : class state_transition;
     144              :   class state_transition_at_call;
     145              :   class state_transition_at_return;
     146              : class uncertainty_t;
     147              : 
     148              : class feasible_node;
     149              : 
     150              : class known_function;
     151              :   class builtin_known_function;
     152              :   class internal_known_function;
     153              : 
     154              : class translation_unit;
     155              : 
     156              : /* Forward decls of functions.  */
     157              : 
     158              : extern void dump_tree (pretty_printer *pp, tree t);
     159              : extern void dump_quoted_tree (pretty_printer *pp, tree t);
     160              : extern void print_quoted_type (pretty_printer *pp, tree t);
     161              : extern void print_expr_for_user (pretty_printer *pp, tree t);
     162              : extern bool printable_expr_p (const_tree expr);
     163              : extern int readability_comparator (const void *p1, const void *p2);
     164              : extern int tree_cmp (const void *p1, const void *p2);
     165              : extern tree fixup_tree_for_diagnostic (tree);
     166              : extern tree get_diagnostic_tree_for_gassign (const gassign *);
     167              : 
     168              : inline bool
     169       161659 : useful_location_p (location_t loc)
     170              : {
     171       161659 :   return get_pure_location (loc) != UNKNOWN_LOCATION;
     172              : }
     173              : 
     174              : /* A tree, extended with stack frame information for locals, so that
     175              :    we can distinguish between different values of locals within a potentially
     176              :    recursive callstack.  */
     177              : 
     178              : class path_var
     179              : {
     180              : public:
     181        25420 :   path_var (tree t, int stack_depth)
     182      4891275 :   : m_tree (t), m_stack_depth (stack_depth)
     183              :   {
     184              :     // TODO: ignore stack depth for globals and constants
     185              :   }
     186              : 
     187           40 :   bool operator== (const path_var &other) const
     188              :   {
     189           40 :     return (m_tree == other.m_tree
     190           40 :             && m_stack_depth == other.m_stack_depth);
     191              :   }
     192              : 
     193         9769 :   operator bool () const
     194              :   {
     195         9769 :     return m_tree != NULL_TREE;
     196              :   }
     197              : 
     198              :   void dump (pretty_printer *pp) const;
     199              : 
     200              :   tree m_tree;
     201              :   int m_stack_depth; // or -1 for globals?
     202              : };
     203              : 
     204              : typedef offset_int bit_offset_t;
     205              : typedef offset_int bit_size_t;
     206              : typedef offset_int byte_offset_t;
     207              : typedef offset_int byte_size_t;
     208              : 
     209              : extern bool int_size_in_bits (const_tree type, bit_size_t *out);
     210              : 
     211              : extern tree get_field_at_bit_offset (tree record_type, bit_offset_t bit_offset);
     212              : 
     213              : extern bool
     214              : compare_bit_offsets_p (bit_offset_t a,
     215              :                        enum tree_code op,
     216              :                        bit_offset_t b);
     217              : 
     218              : /* The location of a region expressesd as an offset relative to a
     219              :    base region.  */
     220              : 
     221              : class region_offset
     222              : {
     223              : public:
     224         1291 :   region_offset ()
     225         1291 :   : m_base_region (nullptr), m_offset (0), m_sym_offset (nullptr)
     226              :   {
     227              :   }
     228              : 
     229       153253 :   static region_offset make_concrete (const region *base_region,
     230              :                                       bit_offset_t offset)
     231              :   {
     232       153253 :     return region_offset (base_region, offset, nullptr);
     233              :   }
     234         4035 :   static region_offset make_symbolic (const region *base_region,
     235              :                                       const svalue *sym_offset)
     236              :   {
     237         4035 :     return region_offset (base_region, 0, sym_offset);
     238              :   }
     239              :   static region_offset make_byte_offset (const region *base_region,
     240              :                                          const svalue *num_bytes_sval);
     241              : 
     242       871729 :   const region *get_base_region () const { return m_base_region; }
     243              : 
     244         4025 :   bool concrete_p () const { return m_sym_offset == nullptr; }
     245      4898252 :   bool symbolic_p () const { return m_sym_offset != nullptr; }
     246              : 
     247      3305818 :   bit_offset_t get_bit_offset () const
     248              :   {
     249      3305818 :     gcc_assert (!symbolic_p ());
     250      3305818 :     return m_offset;
     251              :   }
     252              : 
     253         8603 :   bool get_concrete_byte_offset (byte_offset_t *out) const
     254              :   {
     255         8603 :     gcc_assert (!symbolic_p ());
     256         8603 :     if (m_offset % BITS_PER_UNIT == 0)
     257              :       {
     258         8603 :         *out = m_offset / BITS_PER_UNIT;
     259         8603 :         return true;
     260              :       }
     261              :     return false;
     262              :   }
     263              : 
     264        15107 :   const svalue *get_symbolic_byte_offset () const
     265              :   {
     266        15107 :     gcc_assert (symbolic_p ());
     267        15107 :     return m_sym_offset;
     268              :   }
     269              : 
     270              :   const svalue &calc_symbolic_bit_offset (region_model_manager *mgr) const;
     271              :   const svalue *calc_symbolic_byte_offset (region_model_manager *mgr) const;
     272              : 
     273              :   bool operator== (const region_offset &other) const
     274              :   {
     275              :     return (m_base_region == other.m_base_region
     276              :             && m_offset == other.m_offset
     277              :             && m_sym_offset == other.m_sym_offset);
     278              :   }
     279              : 
     280              :   void dump_to_pp (pretty_printer *pp, bool) const;
     281              :   void dump (bool) const;
     282              : 
     283              : private:
     284       153714 :   region_offset (const region *base_region, bit_offset_t offset,
     285              :                  const svalue *sym_offset)
     286       151800 :   : m_base_region (base_region), m_offset (offset), m_sym_offset (sym_offset)
     287              :   {}
     288              : 
     289              :   const region *m_base_region;
     290              :   bit_offset_t m_offset;
     291              :   const svalue *m_sym_offset;
     292              : };
     293              : 
     294              : extern bool operator< (const region_offset &, const region_offset &);
     295              : extern bool operator<= (const region_offset &, const region_offset &);
     296              : extern bool operator> (const region_offset &, const region_offset &);
     297              : extern bool operator>= (const region_offset &, const region_offset &);
     298              : 
     299              : extern tristate
     300              : eval_region_offset_comparison (region_offset lhs_offset,
     301              :                                enum tree_code op,
     302              :                                region_offset rhs_offset,
     303              :                                const region_model &model);
     304              : 
     305              : extern location_t get_stmt_location (const gimple *stmt, function *fun);
     306              : 
     307              : extern bool compat_types_p (tree src_type, tree dst_type);
     308              : 
     309              : /* Abstract base class for simulating the behavior of known functions,
     310              :    supplied by the core of the analyzer, or by plugins.
     311              :    The former are typically implemented in the various kf*.cc  */
     312              : 
     313       194544 : class known_function
     314              : {
     315              : public:
     316          487 :   virtual ~known_function () {}
     317              :   virtual bool matches_call_types_p (const call_details &cd) const = 0;
     318              : 
     319              :   /* A hook for performing additional checks on the expected state
     320              :      at a call.  */
     321              :   virtual void
     322        34130 :   check_any_preconditions (const call_details &) const
     323              :   {
     324              :     // no-op
     325        34130 :   }
     326              : 
     327        16221 :   virtual void impl_call_pre (const call_details &) const
     328              :   {
     329        16221 :     return;
     330              :   }
     331        34788 :   virtual void impl_call_post (const call_details &) const
     332              :   {
     333        34788 :     return;
     334              :   }
     335              : 
     336              :   virtual const builtin_known_function *
     337        51770 :   dyn_cast_builtin_kf () const { return nullptr; }
     338              : };
     339              : 
     340              : /* Subclass of known_function for builtin functions.  */
     341              : 
     342       177174 : class builtin_known_function : public known_function
     343              : {
     344              : public:
     345              :   virtual enum built_in_function builtin_code () const = 0;
     346        63778 :   tree builtin_decl () const {
     347        63778 :     gcc_assert (builtin_code () < END_BUILTINS);
     348        63778 :     return builtin_info[builtin_code ()].decl;
     349              :   }
     350              : 
     351              :   const builtin_known_function *
     352        63778 :   dyn_cast_builtin_kf () const final override { return this; }
     353              : };
     354              : 
     355              : /* Subclass of known_function for IFN_* functions.  */
     356              : 
     357       274446 : class internal_known_function : public known_function
     358              : {
     359              : public:
     360            0 :   bool matches_call_types_p (const call_details &) const final override
     361              :   {
     362              :     /* Types are assumed to be correct.  */
     363            0 :     return true;
     364              :   }
     365              : };
     366              : 
     367              : /* Abstract subclass of known_function that merely sets the return
     368              :    value of the function (based on function attributes), and assumes
     369              :    it has no side-effects.  */
     370              : 
     371       107694 : class pure_known_function_with_default_return : public known_function
     372              : {
     373              : public:
     374              :   void impl_call_pre (const call_details &cd) const override;
     375              : };
     376              : 
     377              : extern void register_known_functions (known_function_manager &kfm,
     378              :                                       region_model_manager &rmm);
     379              : extern void register_known_analyzer_functions (known_function_manager &kfm);
     380              : extern void register_known_fd_functions (known_function_manager &kfm);
     381              : extern void register_known_file_functions (known_function_manager &kfm);
     382              : extern void register_known_functions_lang_cp (known_function_manager &kfm);
     383              : extern void register_varargs_builtins (known_function_manager &kfm);
     384              : 
     385              : /* An enum for describing the direction of an access to memory.  */
     386              : 
     387              : enum class access_direction
     388              : {
     389              :   read,
     390              :   write
     391              : };
     392              : 
     393              : /* State tracked along an execution path that's pertinent to a specific
     394              :    diagnostic (e.g. for a divide-by-zero warning where the zero value
     395              :    comes from).  */
     396              : 
     397       477925 : struct diagnostic_state
     398              : {
     399        90222 :   diagnostic_state ()
     400        90222 :   : m_region_holding_value (nullptr)
     401              :   {
     402              :   }
     403              : 
     404         1198 :   diagnostic_state (std::string debug_desc,
     405              :                    const region *region_holding_value)
     406         1198 :   : m_debug_desc (std::move (debug_desc)),
     407         1198 :     m_region_holding_value (region_holding_value)
     408              :   {
     409              :   }
     410              : 
     411              :   void dump_to_pp (pretty_printer *) const;
     412              :   void dump () const;
     413              : 
     414              :   bool
     415              :   operator== (const diagnostic_state &other) const
     416              :   {
     417              :     return m_region_holding_value == other.m_region_holding_value;
     418              :   }
     419              :   bool
     420              :   operator!= (const diagnostic_state &other) const
     421              :   {
     422              :     return !(*this == other);
     423              :   }
     424              : 
     425              :   std::string m_debug_desc;
     426              :   const region *m_region_holding_value;
     427              : };
     428              : 
     429              : struct rewind_context;
     430              : 
     431              : /* Abstract base class for associating custom data with an
     432              :    exploded_edge, for handling non-standard edges such as
     433              :    rewinding from a longjmp, signal handlers, etc.
     434              :    Also used when "bifurcating" state: splitting the execution
     435              :    path in non-standard ways (e.g. for simulating the various
     436              :    outcomes of "realloc").  */
     437              : 
     438        32910 : class custom_edge_info
     439              : {
     440              : public:
     441           25 :   virtual ~custom_edge_info () {}
     442              : 
     443              :   /* Hook for making .dot label more readable.  */
     444              :   virtual void print (pretty_printer *pp) const = 0;
     445              : 
     446              :   virtual void
     447              :   get_dot_attrs (const char *&out_style,
     448              :                  const char *&out_color) const;
     449              : 
     450              :   /* Hook for updating STATE when handling bifurcation.  */
     451              :   virtual bool update_state (program_state *state,
     452              :                              const exploded_edge *eedge,
     453              :                              region_model_context *ctxt) const;
     454              : 
     455              :   /* Hook for updating MODEL within exploded_path::feasible_p
     456              :      and when handling bifurcation.  */
     457              :   virtual bool update_model (region_model *model,
     458              :                              const exploded_edge *eedge,
     459              :                              region_model_context *ctxt) const = 0;
     460              : 
     461              :   virtual void add_events_to_path (checker_path *emission_path,
     462              :                                    const exploded_edge &eedge,
     463              :                                    pending_diagnostic &pd,
     464              :                                    const state_transition *state_trans) const = 0;
     465              : 
     466              :   virtual exploded_node *create_enode (exploded_graph &eg,
     467              :                                        const program_point &point,
     468              :                                        program_state &&state,
     469              :                                        exploded_node *enode_for_diag,
     470              :                                        region_model_context *ctxt) const;
     471              : 
     472              :   virtual bool
     473          475 :   try_to_rewind_data_flow (rewind_context &) const
     474              :   {
     475          475 :     return false;
     476              :   }
     477              : };
     478              : 
     479              : /* Abstract base class for splitting state.
     480              : 
     481              :    Most of the state-management code in the analyzer involves
     482              :    modifying state objects in-place, which assumes a single outcome.
     483              : 
     484              :    This class provides an escape hatch to allow for multiple outcomes
     485              :    for such updates e.g. for modelling multiple outcomes from function
     486              :    calls, such as the various outcomes of "realloc".  */
     487              : 
     488       253834 : class path_context
     489              : {
     490              : public:
     491       114660 :   virtual ~path_context () {}
     492              : 
     493              :   /* Hook for clients to split state with a non-standard path.  */
     494              :   virtual void bifurcate (std::unique_ptr<custom_edge_info> info) = 0;
     495              : 
     496              :   /* Hook for clients to terminate the standard path.  */
     497              :   virtual void terminate_path () = 0;
     498              : 
     499              :   /* Hook for clients to determine if the standard path has been
     500              :      terminated.  */
     501              :   virtual bool terminate_path_p () const = 0;
     502              : };
     503              : 
     504              : extern tree get_stashed_constant_by_name (const char *name);
     505              : extern void log_stashed_constants (logger *logger);
     506              : 
     507              : extern FILE *get_or_create_any_logfile ();
     508              : 
     509              : extern std::unique_ptr<json::value>
     510              : tree_to_json (tree node);
     511              : 
     512              : extern std::unique_ptr<json::value>
     513              : diagnostic_event_id_to_json (const diagnostics::paths::event_id_t &);
     514              : 
     515              : extern std::unique_ptr<json::value>
     516              : bit_offset_to_json (const bit_offset_t &offset);
     517              : 
     518              : extern std::unique_ptr<json::value>
     519              : byte_offset_to_json (const byte_offset_t &offset);
     520              : 
     521              : extern tristate
     522              : compare_constants (tree lhs_const, enum tree_code op, tree rhs_const);
     523              : 
     524              : extern tree
     525              : get_string_cst_size (const_tree string_cst);
     526              : 
     527              : extern tree
     528              : get_ssa_default_def (const function &fun, tree var);
     529              : 
     530              : extern const svalue *
     531              : strip_types (const svalue *sval, region_model_manager &mgr);
     532              : 
     533              : extern region_offset
     534              : strip_types (const region_offset &offset, region_model_manager &mgr);
     535              : 
     536              : extern tree remove_ssa_names (tree expr);
     537              : 
     538              : } // namespace ana
     539              : 
     540              : extern bool is_special_named_call_p (const gcall &call, const char *funcname,
     541              :                                      unsigned int num_args,
     542              :                                      bool look_in_std = false);
     543              : extern bool is_named_call_p (const_tree fndecl, const char *funcname);
     544              : extern bool is_named_call_p (const_tree fndecl, const char *funcname,
     545              :                              const gcall &call, unsigned int num_args);
     546              : extern bool is_std_function_p (const_tree fndecl);
     547              : extern bool is_std_named_call_p (const_tree fndecl, const char *funcname);
     548              : extern bool is_std_named_call_p (const_tree fndecl, const char *funcname,
     549              :                                  const gcall &call, unsigned int num_args);
     550              : extern bool is_setjmp_call_p (const gcall &call);
     551              : extern bool is_longjmp_call_p (const gcall &call);
     552              : extern bool is_placement_new_p (const gcall &call);
     553              : extern bool is_cxa_throw_p (const gcall &call);
     554              : extern bool is_cxa_rethrow_p (const gcall &call);
     555              : extern bool is_cxa_end_catch_p (const gcall &call);
     556              : 
     557              : extern const char *get_user_facing_name (const gcall &call);
     558              : 
     559              : extern void register_analyzer_pass ();
     560              : 
     561              : extern label_text make_label_text (bool can_colorize, const char *fmt, ...);
     562              : extern label_text make_label_text_n (bool can_colorize,
     563              :                                      unsigned HOST_WIDE_INT n,
     564              :                                      const char *singular_fmt,
     565              :                                      const char *plural_fmt, ...);
     566              : 
     567              : extern bool fndecl_has_gimple_body_p (tree fndecl);
     568              : 
     569              : /* An RAII-style class for pushing/popping cfun within a scope.
     570              :    Doing so ensures we get "In function " announcements
     571              :    from the diagnostics subsystem.  */
     572              : 
     573              : class auto_cfun
     574              : {
     575              : public:
     576       809261 :   auto_cfun (function *fun) { push_cfun (fun); }
     577       809261 :   ~auto_cfun () { pop_cfun (); }
     578              : };
     579              : 
     580              : /* A template for creating hash traits for a POD type.  */
     581              : 
     582              : template <typename Type>
     583              : struct pod_hash_traits : typed_noop_remove<Type>
     584              : {
     585              :   typedef Type value_type;
     586              :   typedef Type compare_type;
     587              :   static inline hashval_t hash (value_type);
     588              :   static inline bool equal (const value_type &existing,
     589              :                             const value_type &candidate);
     590              :   static inline void mark_deleted (Type &);
     591              :   static inline void mark_empty (Type &);
     592              :   static inline bool is_deleted (Type);
     593              :   static inline bool is_empty (Type);
     594              : };
     595              : 
     596              : /* A hash traits class that uses member functions to implement
     597              :    the various required ops.  */
     598              : 
     599              : template <typename Type>
     600              : struct member_function_hash_traits : public typed_noop_remove<Type>
     601              : {
     602              :   typedef Type value_type;
     603              :   typedef Type compare_type;
     604    101407362 :   static inline hashval_t hash (value_type v) { return v.hash (); }
     605     97084589 :   static inline bool equal (const value_type &existing,
     606              :                             const value_type &candidate)
     607              :   {
     608    120314407 :     return existing == candidate;
     609              :   }
     610              :   static inline void mark_deleted (Type &t) { t.mark_deleted (); }
     611       891052 :   static inline void mark_empty (Type &t) { t.mark_empty (); }
     612     68297623 :   static inline bool is_deleted (Type t) { return t.is_deleted (); }
     613    326625047 :   static inline bool is_empty (Type t) { return t.is_empty (); }
     614              : };
     615              : 
     616              : /* A map from T::key_t to T* for use in consolidating instances of T.
     617              :    Owns all instances of T.
     618              :    T::key_t should have operator== and be hashable.  */
     619              : 
     620              : template <typename T>
     621              : class consolidation_map
     622              : {
     623              : public:
     624              :   typedef typename T::key_t key_t;
     625              :   typedef T instance_t;
     626              :   typedef hash_map<key_t, instance_t *> inner_map_t;
     627              :   typedef typename inner_map_t::iterator iterator;
     628              : 
     629              :   /* Delete all instances of T.  */
     630              : 
     631        44390 :   ~consolidation_map ()
     632              :   {
     633       129914 :     for (typename inner_map_t::iterator iter = m_inner_map.begin ();
     634       215438 :          iter != m_inner_map.end (); ++iter)
     635        85524 :       delete (*iter).second;
     636        44390 :   }
     637              : 
     638              :   /* Get the instance of T for K if one exists, or nullptr.  */
     639              : 
     640     16051008 :   T *get (const key_t &k) const
     641              :   {
     642     16051008 :     if (instance_t **slot = const_cast<inner_map_t &> (m_inner_map).get (k))
     643     15965484 :       return *slot;
     644              :     return nullptr;
     645              :   }
     646              : 
     647              :   /* Take ownership of INSTANCE.  */
     648              : 
     649        85524 :   void put (const key_t &k, T *instance)
     650              :   {
     651        85524 :     m_inner_map.put (k, instance);
     652              :   }
     653              : 
     654          110 :   size_t elements () const { return m_inner_map.elements (); }
     655              : 
     656           78 :   iterator begin () const { return m_inner_map.begin (); }
     657          126 :   iterator end () const { return m_inner_map.end (); }
     658              : 
     659              : private:
     660              :   inner_map_t m_inner_map;
     661              : };
     662              : 
     663              : /* Disable -Wformat-diag; we want to be able to use pp_printf
     664              :    for logging/dumping without complying with the rules for diagnostics.  */
     665              : #if __GNUC__ >= 10
     666              : #pragma GCC diagnostic ignored "-Wformat-diag"
     667              : #endif
     668              : 
     669              : namespace gcc {
     670              : namespace topics {
     671              : 
     672              : /* A topic for messages relating to the analyzer.  */
     673              : 
     674              : namespace analyzer_events {
     675              : 
     676              : /* A message published by the analyzer when the frontend finishes
     677              :    parsing the TU, to allow it to look up pertinent items using the FE's
     678              :    name-resolution logic.  */
     679              : 
     680              : struct on_tu_finished
     681              : {
     682              :   ana::logger *m_logger;
     683              :   const ana::translation_unit &m_tu;
     684              : };
     685              : 
     686              : /* A message published by the analyzer as it starts up, intended for
     687              :    subsystems/plugins that want to register additional functionality
     688              :    within the analyzer.  */
     689              : 
     690           38 : struct on_ana_init
     691              : {
     692              :   virtual void
     693              :   register_state_machine (std::unique_ptr<ana::state_machine>) const = 0;
     694              : 
     695              :   virtual void
     696              :   register_known_function (const char *name,
     697              :                            std::unique_ptr<ana::known_function>) const = 0;
     698              : 
     699              :   virtual ana::logger *
     700              :   get_logger () const = 0;
     701              : };
     702              : 
     703              : /* A message published by the analyzer when it simulates popping a stack
     704              :    frame.  */
     705              : 
     706              : struct on_frame_popped
     707              : {
     708              :   const ana::region_model *m_new_model;
     709              :   const ana::region_model *m_old_model;
     710              :   const ana::svalue *m_retval;
     711              :   ana::region_model_context *m_ctxt;
     712              : };
     713              : 
     714              : struct subscriber {
     715              : 
     716              :   virtual ~subscriber () = default;
     717              : 
     718           37 :   virtual void on_message (const on_tu_finished &) {}
     719            0 :   virtual void on_message (const on_ana_init &) {}
     720          236 :   virtual void on_message (const on_frame_popped &) {}
     721              : };
     722              : 
     723              : } // namespace gcc::topics::analyzer_events
     724              : } // namespace gcc::topics
     725              : } // namespace gcc
     726              : 
     727              : #if !ENABLE_ANALYZER
     728              : extern void sorry_no_analyzer ();
     729              : #endif /* #if !ENABLE_ANALYZER */
     730              : 
     731              : #endif /* GCC_ANALYZER_COMMON_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.