LCOV - code coverage report
Current view: top level - gcc/analyzer - common.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 97.2 % 71 69
Test Date: 2025-07-26 09:32:30 Functions: 95.2 % 21 20
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Base header for the analyzer, plus utility functions.
       2                 :             :    Copyright (C) 2019-2025 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_MAP
      26                 :             : #define INCLUDE_STRING
      27                 :             : #define INCLUDE_VECTOR
      28                 :             : #include "system.h"
      29                 :             : #include "coretypes.h"
      30                 :             : #include "tree.h"
      31                 :             : #include "function.h"
      32                 :             : #include "basic-block.h"
      33                 :             : #include "gimple.h"
      34                 :             : #include "options.h"
      35                 :             : #include "bitmap.h"
      36                 :             : #include "diagnostic-core.h"
      37                 :             : #include "diagnostics/paths.h"
      38                 :             : #include "rich-location.h"
      39                 :             : #include "function.h"
      40                 :             : #include "json.h"
      41                 :             : #include "tristate.h"
      42                 :             : 
      43                 :             : class graphviz_out;
      44                 :             : 
      45                 :             : namespace ana {
      46                 :             : 
      47                 :             : /* Forward decls of common types, with indentation to show inheritance.  */
      48                 :             : 
      49                 :             : class supergraph;
      50                 :             : class supernode;
      51                 :             : class superedge;
      52                 :             :   class cfg_superedge;
      53                 :             :     class switch_cfg_superedge;
      54                 :             :     class eh_dispatch_cfg_superedge;
      55                 :             :       class eh_dispatch_try_cfg_superedge;
      56                 :             :       class eh_dispatch_allowed_cfg_superedge;
      57                 :             :   class callgraph_superedge;
      58                 :             :     class call_superedge;
      59                 :             :     class return_superedge;
      60                 :             : 
      61                 :             : class svalue;
      62                 :             :   class region_svalue;
      63                 :             :   class constant_svalue;
      64                 :             :   class unknown_svalue;
      65                 :             :   class poisoned_svalue;
      66                 :             :   class setjmp_svalue;
      67                 :             :   class initial_svalue;
      68                 :             :   class unaryop_svalue;
      69                 :             :   class binop_svalue;
      70                 :             :   class sub_svalue;
      71                 :             :   class repeated_svalue;
      72                 :             :   class bits_within_svalue;
      73                 :             :   class unmergeable_svalue;
      74                 :             :   class placeholder_svalue;
      75                 :             :   class widening_svalue;
      76                 :             :   class compound_svalue;
      77                 :             :   class conjured_svalue;
      78                 :             :   class asm_output_svalue;
      79                 :             :   class const_fn_result_svalue;
      80                 :             : typedef hash_set<const svalue *> svalue_set;
      81                 :             : class region;
      82                 :             :   class frame_region;
      83                 :             :   class function_region;
      84                 :             :   class label_region;
      85                 :             :   class decl_region;
      86                 :             :   class symbolic_region;
      87                 :             :   class element_region;
      88                 :             :   class offset_region;
      89                 :             :   class sized_region;
      90                 :             :   class cast_region;
      91                 :             :   class field_region;
      92                 :             :   class string_region;
      93                 :             :   class bit_range_region;
      94                 :             :   class var_arg_region;
      95                 :             : class region_model_manager;
      96                 :             : class conjured_purge;
      97                 :             : struct model_merger;
      98                 :             : class store_manager;
      99                 :             : class store;
     100                 :             : class region_model;
     101                 :             : class region_model_context;
     102                 :             :   class impl_region_model_context;
     103                 :             : class call_details;
     104                 :             : class rejected_constraint;
     105                 :             : class constraint_manager;
     106                 :             : class equiv_class;
     107                 :             : class reachable_regions;
     108                 :             : class bounded_ranges;
     109                 :             : class bounded_ranges_manager;
     110                 :             : 
     111                 :             : struct pending_location;
     112                 :             : class pending_diagnostic;
     113                 :             : class pending_note;
     114                 :             : class saved_diagnostic;
     115                 :             : struct event_loc_info;
     116                 :             : class checker_event;
     117                 :             :   class state_change_event;
     118                 :             :   class warning_event;
     119                 :             : class checker_path;
     120                 :             : class extrinsic_state;
     121                 :             : class sm_state_map;
     122                 :             : class stmt_finder;
     123                 :             : class program_point;
     124                 :             : class function_point;
     125                 :             : class program_state;
     126                 :             : class exploded_graph;
     127                 :             : class exploded_node;
     128                 :             : class exploded_edge;
     129                 :             : class feasibility_problem;
     130                 :             : class exploded_cluster;
     131                 :             : class exploded_path;
     132                 :             : class analysis_plan;
     133                 :             : class state_purge_map;
     134                 :             : class state_purge_per_ssa_name;
     135                 :             : class state_purge_per_decl;
     136                 :             : class state_change;
     137                 :             : class rewind_info_t;
     138                 :             : 
     139                 :             : class engine;
     140                 :             : class state_machine;
     141                 :             : class logger;
     142                 :             : class visitor;
     143                 :             : class known_function_manager;
     144                 :             : class call_summary;
     145                 :             : class call_summary_replay;
     146                 :             : struct per_function_data;
     147                 :             : struct interesting_t;
     148                 :             : 
     149                 :             : class feasible_node;
     150                 :             : 
     151                 :             : class known_function;
     152                 :             :   class builtin_known_function;
     153                 :             :   class internal_known_function;
     154                 :             : 
     155                 :             : /* Forward decls of functions.  */
     156                 :             : 
     157                 :             : extern void dump_tree (pretty_printer *pp, tree t);
     158                 :             : extern void dump_quoted_tree (pretty_printer *pp, tree t);
     159                 :             : extern void print_quoted_type (pretty_printer *pp, tree t);
     160                 :             : extern void print_expr_for_user (pretty_printer *pp, tree t);
     161                 :             : extern int readability_comparator (const void *p1, const void *p2);
     162                 :             : extern int tree_cmp (const void *p1, const void *p2);
     163                 :             : extern tree fixup_tree_for_diagnostic (tree);
     164                 :             : extern tree get_diagnostic_tree_for_gassign (const gassign *);
     165                 :             : 
     166                 :             : /* A tree, extended with stack frame information for locals, so that
     167                 :             :    we can distinguish between different values of locals within a potentially
     168                 :             :    recursive callstack.  */
     169                 :             : 
     170                 :             : class path_var
     171                 :             : {
     172                 :             : public:
     173                 :       27610 :   path_var (tree t, int stack_depth)
     174                 :     4387952 :   : m_tree (t), m_stack_depth (stack_depth)
     175                 :             :   {
     176                 :             :     // TODO: ignore stack depth for globals and constants
     177                 :             :   }
     178                 :             : 
     179                 :          40 :   bool operator== (const path_var &other) const
     180                 :             :   {
     181                 :          40 :     return (m_tree == other.m_tree
     182                 :          40 :             && m_stack_depth == other.m_stack_depth);
     183                 :             :   }
     184                 :             : 
     185                 :       11058 :   operator bool () const
     186                 :             :   {
     187                 :       11058 :     return m_tree != NULL_TREE;
     188                 :             :   }
     189                 :             : 
     190                 :             :   void dump (pretty_printer *pp) const;
     191                 :             : 
     192                 :             :   tree m_tree;
     193                 :             :   int m_stack_depth; // or -1 for globals?
     194                 :             : };
     195                 :             : 
     196                 :             : typedef offset_int bit_offset_t;
     197                 :             : typedef offset_int bit_size_t;
     198                 :             : typedef offset_int byte_offset_t;
     199                 :             : typedef offset_int byte_size_t;
     200                 :             : 
     201                 :             : extern bool int_size_in_bits (const_tree type, bit_size_t *out);
     202                 :             : 
     203                 :             : extern tree get_field_at_bit_offset (tree record_type, bit_offset_t bit_offset);
     204                 :             : 
     205                 :             : /* The location of a region expressesd as an offset relative to a
     206                 :             :    base region.  */
     207                 :             : 
     208                 :             : class region_offset
     209                 :             : {
     210                 :             : public:
     211                 :        1291 :   region_offset ()
     212                 :        1291 :   : m_base_region (nullptr), m_offset (0), m_sym_offset (nullptr)
     213                 :             :   {
     214                 :             :   }
     215                 :             : 
     216                 :      141662 :   static region_offset make_concrete (const region *base_region,
     217                 :             :                                       bit_offset_t offset)
     218                 :             :   {
     219                 :      141662 :     return region_offset (base_region, offset, nullptr);
     220                 :             :   }
     221                 :        4116 :   static region_offset make_symbolic (const region *base_region,
     222                 :             :                                       const svalue *sym_offset)
     223                 :             :   {
     224                 :        4116 :     return region_offset (base_region, 0, sym_offset);
     225                 :             :   }
     226                 :             :   static region_offset make_byte_offset (const region *base_region,
     227                 :             :                                          const svalue *num_bytes_sval);
     228                 :             : 
     229                 :      697596 :   const region *get_base_region () const { return m_base_region; }
     230                 :             : 
     231                 :        2990 :   bool concrete_p () const { return m_sym_offset == nullptr; }
     232                 :     4573440 :   bool symbolic_p () const { return m_sym_offset != nullptr; }
     233                 :             : 
     234                 :     3012449 :   bit_offset_t get_bit_offset () const
     235                 :             :   {
     236                 :     3012449 :     gcc_assert (!symbolic_p ());
     237                 :     3012449 :     return m_offset;
     238                 :             :   }
     239                 :             : 
     240                 :        7970 :   bool get_concrete_byte_offset (byte_offset_t *out) const
     241                 :             :   {
     242                 :        7970 :     gcc_assert (!symbolic_p ());
     243                 :        7970 :     if (m_offset % BITS_PER_UNIT == 0)
     244                 :             :       {
     245                 :        7970 :         *out = m_offset / BITS_PER_UNIT;
     246                 :        7970 :         return true;
     247                 :             :       }
     248                 :             :     return false;
     249                 :             :   }
     250                 :             : 
     251                 :       14950 :   const svalue *get_symbolic_byte_offset () const
     252                 :             :   {
     253                 :       14950 :     gcc_assert (symbolic_p ());
     254                 :       14950 :     return m_sym_offset;
     255                 :             :   }
     256                 :             : 
     257                 :             :   const svalue &calc_symbolic_bit_offset (region_model_manager *mgr) const;
     258                 :             :   const svalue *calc_symbolic_byte_offset (region_model_manager *mgr) const;
     259                 :             : 
     260                 :             :   bool operator== (const region_offset &other) const
     261                 :             :   {
     262                 :             :     return (m_base_region == other.m_base_region
     263                 :             :             && m_offset == other.m_offset
     264                 :             :             && m_sym_offset == other.m_sym_offset);
     265                 :             :   }
     266                 :             : 
     267                 :             :   void dump_to_pp (pretty_printer *pp, bool) const;
     268                 :             :   void dump (bool) const;
     269                 :             : 
     270                 :             : private:
     271                 :      142208 :   region_offset (const region *base_region, bit_offset_t offset,
     272                 :             :                  const svalue *sym_offset)
     273                 :      140209 :   : m_base_region (base_region), m_offset (offset), m_sym_offset (sym_offset)
     274                 :             :   {}
     275                 :             : 
     276                 :             :   const region *m_base_region;
     277                 :             :   bit_offset_t m_offset;
     278                 :             :   const svalue *m_sym_offset;
     279                 :             : };
     280                 :             : 
     281                 :             : extern bool operator< (const region_offset &, const region_offset &);
     282                 :             : extern bool operator<= (const region_offset &, const region_offset &);
     283                 :             : extern bool operator> (const region_offset &, const region_offset &);
     284                 :             : extern bool operator>= (const region_offset &, const region_offset &);
     285                 :             : 
     286                 :             : extern location_t get_stmt_location (const gimple *stmt, function *fun);
     287                 :             : 
     288                 :             : extern bool compat_types_p (tree src_type, tree dst_type);
     289                 :             : 
     290                 :             : /* Abstract base class for simulating the behavior of known functions,
     291                 :             :    supplied by the core of the analyzer, or by plugins.
     292                 :             :    The former are typically implemented in the various kf*.cc  */
     293                 :             : 
     294                 :      164050 : class known_function
     295                 :             : {
     296                 :             : public:
     297                 :         369 :   virtual ~known_function () {}
     298                 :             :   virtual bool matches_call_types_p (const call_details &cd) const = 0;
     299                 :       18930 :   virtual void impl_call_pre (const call_details &) const
     300                 :             :   {
     301                 :       18930 :     return;
     302                 :             :   }
     303                 :       31758 :   virtual void impl_call_post (const call_details &) const
     304                 :             :   {
     305                 :       31758 :     return;
     306                 :             :   }
     307                 :             : 
     308                 :             :   virtual const builtin_known_function *
     309                 :       49794 :   dyn_cast_builtin_kf () const { return nullptr; }
     310                 :             : };
     311                 :             : 
     312                 :             : /* Subclass of known_function for builtin functions.  */
     313                 :             : 
     314                 :      157488 : class builtin_known_function : public known_function
     315                 :             : {
     316                 :             : public:
     317                 :             :   virtual enum built_in_function builtin_code () const = 0;
     318                 :       67928 :   tree builtin_decl () const {
     319                 :       67928 :     gcc_assert (builtin_code () < END_BUILTINS);
     320                 :       67928 :     return builtin_info[builtin_code ()].decl;
     321                 :             :   }
     322                 :             : 
     323                 :             :   const builtin_known_function *
     324                 :       67928 :   dyn_cast_builtin_kf () const final override { return this; }
     325                 :             : };
     326                 :             : 
     327                 :             : /* Subclass of known_function for IFN_* functions.  */
     328                 :             : 
     329                 :      495431 : class internal_known_function : public known_function
     330                 :             : {
     331                 :             : public:
     332                 :           0 :   bool matches_call_types_p (const call_details &) const final override
     333                 :             :   {
     334                 :             :     /* Types are assumed to be correct.  */
     335                 :           0 :     return true;
     336                 :             :   }
     337                 :             : };
     338                 :             : 
     339                 :             : /* Abstract subclass of known_function that merely sets the return
     340                 :             :    value of the function (based on function attributes), and assumes
     341                 :             :    it has no side-effects.  */
     342                 :             : 
     343                 :       88587 : class pure_known_function_with_default_return : public known_function
     344                 :             : {
     345                 :             : public:
     346                 :             :   void impl_call_pre (const call_details &cd) const override;
     347                 :             : };
     348                 :             : 
     349                 :             : extern void register_known_functions (known_function_manager &kfm,
     350                 :             :                                       region_model_manager &rmm);
     351                 :             : extern void register_known_analyzer_functions (known_function_manager &kfm);
     352                 :             : extern void register_known_fd_functions (known_function_manager &kfm);
     353                 :             : extern void register_known_file_functions (known_function_manager &kfm);
     354                 :             : extern void register_known_functions_lang_cp (known_function_manager &kfm);
     355                 :             : extern void register_varargs_builtins (known_function_manager &kfm);
     356                 :             : 
     357                 :             : /* Passed by pointer to PLUGIN_ANALYZER_INIT callbacks.  */
     358                 :             : 
     359                 :        3281 : class plugin_analyzer_init_iface
     360                 :             : {
     361                 :             : public:
     362                 :             :   virtual void register_state_machine (std::unique_ptr<state_machine>) = 0;
     363                 :             :   virtual void register_known_function (const char *name,
     364                 :             :                                         std::unique_ptr<known_function>) = 0;
     365                 :             :   virtual logger *get_logger () const = 0;
     366                 :             : };
     367                 :             : 
     368                 :             : /* An enum for describing the direction of an access to memory.  */
     369                 :             : 
     370                 :             : enum class access_direction
     371                 :             : {
     372                 :             :   read,
     373                 :             :   write
     374                 :             : };
     375                 :             : 
     376                 :             : /* Abstract base class for associating custom data with an
     377                 :             :    exploded_edge, for handling non-standard edges such as
     378                 :             :    rewinding from a longjmp, signal handlers, etc.
     379                 :             :    Also used when "bifurcating" state: splitting the execution
     380                 :             :    path in non-standard ways (e.g. for simulating the various
     381                 :             :    outcomes of "realloc").  */
     382                 :             : 
     383                 :       20104 : class custom_edge_info
     384                 :             : {
     385                 :             : public:
     386                 :          25 :   virtual ~custom_edge_info () {}
     387                 :             : 
     388                 :             :   /* Hook for making .dot label more readable.  */
     389                 :             :   virtual void print (pretty_printer *pp) const = 0;
     390                 :             : 
     391                 :             :   /* Hook for updating STATE when handling bifurcation.  */
     392                 :             :   virtual bool update_state (program_state *state,
     393                 :             :                              const exploded_edge *eedge,
     394                 :             :                              region_model_context *ctxt) const;
     395                 :             : 
     396                 :             :   /* Hook for updating MODEL within exploded_path::feasible_p
     397                 :             :      and when handling bifurcation.  */
     398                 :             :   virtual bool update_model (region_model *model,
     399                 :             :                              const exploded_edge *eedge,
     400                 :             :                              region_model_context *ctxt) const = 0;
     401                 :             : 
     402                 :             :   virtual void add_events_to_path (checker_path *emission_path,
     403                 :             :                                    const exploded_edge &eedge) const = 0;
     404                 :             : 
     405                 :             :   virtual exploded_node *create_enode (exploded_graph &eg,
     406                 :             :                                        const program_point &point,
     407                 :             :                                        program_state &&state,
     408                 :             :                                        exploded_node *enode_for_diag,
     409                 :             :                                        region_model_context *ctxt) const;
     410                 :             : };
     411                 :             : 
     412                 :             : /* Abstract base class for splitting state.
     413                 :             : 
     414                 :             :    Most of the state-management code in the analyzer involves
     415                 :             :    modifying state objects in-place, which assumes a single outcome.
     416                 :             : 
     417                 :             :    This class provides an escape hatch to allow for multiple outcomes
     418                 :             :    for such updates e.g. for modelling multiple outcomes from function
     419                 :             :    calls, such as the various outcomes of "realloc".  */
     420                 :             : 
     421                 :      249853 : class path_context
     422                 :             : {
     423                 :             : public:
     424                 :      125734 :   virtual ~path_context () {}
     425                 :             : 
     426                 :             :   /* Hook for clients to split state with a non-standard path.  */
     427                 :             :   virtual void bifurcate (std::unique_ptr<custom_edge_info> info) = 0;
     428                 :             : 
     429                 :             :   /* Hook for clients to terminate the standard path.  */
     430                 :             :   virtual void terminate_path () = 0;
     431                 :             : 
     432                 :             :   /* Hook for clients to determine if the standard path has been
     433                 :             :      terminated.  */
     434                 :             :   virtual bool terminate_path_p () const = 0;
     435                 :             : };
     436                 :             : 
     437                 :             : extern tree get_stashed_constant_by_name (const char *name);
     438                 :             : extern void log_stashed_constants (logger *logger);
     439                 :             : 
     440                 :             : extern FILE *get_or_create_any_logfile ();
     441                 :             : 
     442                 :             : extern std::unique_ptr<json::value>
     443                 :             : tree_to_json (tree node);
     444                 :             : 
     445                 :             : extern std::unique_ptr<json::value>
     446                 :             : diagnostic_event_id_to_json (const diagnostics::paths::event_id_t &);
     447                 :             : 
     448                 :             : extern std::unique_ptr<json::value>
     449                 :             : bit_offset_to_json (const bit_offset_t &offset);
     450                 :             : 
     451                 :             : extern std::unique_ptr<json::value>
     452                 :             : byte_offset_to_json (const byte_offset_t &offset);
     453                 :             : 
     454                 :             : extern tristate
     455                 :             : compare_constants (tree lhs_const, enum tree_code op, tree rhs_const);
     456                 :             : 
     457                 :             : extern tree
     458                 :             : get_string_cst_size (const_tree string_cst);
     459                 :             : 
     460                 :             : extern tree
     461                 :             : get_ssa_default_def (const function &fun, tree var);
     462                 :             : 
     463                 :             : extern const svalue *
     464                 :             : strip_types (const svalue *sval, region_model_manager &mgr);
     465                 :             : 
     466                 :             : extern region_offset
     467                 :             : strip_types (const region_offset &offset, region_model_manager &mgr);
     468                 :             : 
     469                 :             : extern tree remove_ssa_names (tree expr);
     470                 :             : 
     471                 :             : } // namespace ana
     472                 :             : 
     473                 :             : extern bool is_special_named_call_p (const gcall &call, const char *funcname,
     474                 :             :                                      unsigned int num_args,
     475                 :             :                                      bool look_in_std = false);
     476                 :             : extern bool is_named_call_p (const_tree fndecl, const char *funcname);
     477                 :             : extern bool is_named_call_p (const_tree fndecl, const char *funcname,
     478                 :             :                              const gcall &call, unsigned int num_args);
     479                 :             : extern bool is_std_function_p (const_tree fndecl);
     480                 :             : extern bool is_std_named_call_p (const_tree fndecl, const char *funcname);
     481                 :             : extern bool is_std_named_call_p (const_tree fndecl, const char *funcname,
     482                 :             :                                  const gcall &call, unsigned int num_args);
     483                 :             : extern bool is_setjmp_call_p (const gcall &call);
     484                 :             : extern bool is_longjmp_call_p (const gcall &call);
     485                 :             : extern bool is_placement_new_p (const gcall &call);
     486                 :             : extern bool is_cxa_throw_p (const gcall &call);
     487                 :             : extern bool is_cxa_rethrow_p (const gcall &call);
     488                 :             : 
     489                 :             : extern const char *get_user_facing_name (const gcall &call);
     490                 :             : 
     491                 :             : extern void register_analyzer_pass ();
     492                 :             : 
     493                 :             : extern label_text make_label_text (bool can_colorize, const char *fmt, ...);
     494                 :             : extern label_text make_label_text_n (bool can_colorize,
     495                 :             :                                      unsigned HOST_WIDE_INT n,
     496                 :             :                                      const char *singular_fmt,
     497                 :             :                                      const char *plural_fmt, ...);
     498                 :             : 
     499                 :             : extern bool fndecl_has_gimple_body_p (tree fndecl);
     500                 :             : 
     501                 :             : /* An RAII-style class for pushing/popping cfun within a scope.
     502                 :             :    Doing so ensures we get "In function " announcements
     503                 :             :    from the diagnostics subsystem.  */
     504                 :             : 
     505                 :             : class auto_cfun
     506                 :             : {
     507                 :             : public:
     508                 :      839314 :   auto_cfun (function *fun) { push_cfun (fun); }
     509                 :      839314 :   ~auto_cfun () { pop_cfun (); }
     510                 :             : };
     511                 :             : 
     512                 :             : /* A template for creating hash traits for a POD type.  */
     513                 :             : 
     514                 :             : template <typename Type>
     515                 :             : struct pod_hash_traits : typed_noop_remove<Type>
     516                 :             : {
     517                 :             :   typedef Type value_type;
     518                 :             :   typedef Type compare_type;
     519                 :             :   static inline hashval_t hash (value_type);
     520                 :             :   static inline bool equal (const value_type &existing,
     521                 :             :                             const value_type &candidate);
     522                 :             :   static inline void mark_deleted (Type &);
     523                 :             :   static inline void mark_empty (Type &);
     524                 :             :   static inline bool is_deleted (Type);
     525                 :             :   static inline bool is_empty (Type);
     526                 :             : };
     527                 :             : 
     528                 :             : /* A hash traits class that uses member functions to implement
     529                 :             :    the various required ops.  */
     530                 :             : 
     531                 :             : template <typename Type>
     532                 :             : struct member_function_hash_traits : public typed_noop_remove<Type>
     533                 :             : {
     534                 :             :   typedef Type value_type;
     535                 :             :   typedef Type compare_type;
     536                 :    41184072 :   static inline hashval_t hash (value_type v) { return v.hash (); }
     537                 :    38766812 :   static inline bool equal (const value_type &existing,
     538                 :             :                             const value_type &candidate)
     539                 :             :   {
     540                 :    59234449 :     return existing == candidate;
     541                 :             :   }
     542                 :             :   static inline void mark_deleted (Type &t) { t.mark_deleted (); }
     543                 :      848095 :   static inline void mark_empty (Type &t) { t.mark_empty (); }
     544                 :    11798943 :   static inline bool is_deleted (Type t) { return t.is_deleted (); }
     545                 :   117966680 :   static inline bool is_empty (Type t) { return t.is_empty (); }
     546                 :             : };
     547                 :             : 
     548                 :             : /* A map from T::key_t to T* for use in consolidating instances of T.
     549                 :             :    Owns all instances of T.
     550                 :             :    T::key_t should have operator== and be hashable.  */
     551                 :             : 
     552                 :             : template <typename T>
     553                 :             : class consolidation_map
     554                 :             : {
     555                 :             : public:
     556                 :             :   typedef typename T::key_t key_t;
     557                 :             :   typedef T instance_t;
     558                 :             :   typedef hash_map<key_t, instance_t *> inner_map_t;
     559                 :             :   typedef typename inner_map_t::iterator iterator;
     560                 :             : 
     561                 :             :   /* Delete all instances of T.  */
     562                 :             : 
     563                 :       42391 :   ~consolidation_map ()
     564                 :             :   {
     565                 :      118674 :     for (typename inner_map_t::iterator iter = m_inner_map.begin ();
     566                 :      194957 :          iter != m_inner_map.end (); ++iter)
     567                 :       76283 :       delete (*iter).second;
     568                 :       42391 :   }
     569                 :             : 
     570                 :             :   /* Get the instance of T for K if one exists, or nullptr.  */
     571                 :             : 
     572                 :     3833710 :   T *get (const key_t &k) const
     573                 :             :   {
     574                 :     3833710 :     if (instance_t **slot = const_cast<inner_map_t &> (m_inner_map).get (k))
     575                 :     3757427 :       return *slot;
     576                 :             :     return nullptr;
     577                 :             :   }
     578                 :             : 
     579                 :             :   /* Take ownership of INSTANCE.  */
     580                 :             : 
     581                 :       76283 :   void put (const key_t &k, T *instance)
     582                 :             :   {
     583                 :       76283 :     m_inner_map.put (k, instance);
     584                 :             :   }
     585                 :             : 
     586                 :          44 :   size_t elements () const { return m_inner_map.elements (); }
     587                 :             : 
     588                 :          45 :   iterator begin () const { return m_inner_map.begin (); }
     589                 :          68 :   iterator end () const { return m_inner_map.end (); }
     590                 :             : 
     591                 :             : private:
     592                 :             :   inner_map_t m_inner_map;
     593                 :             : };
     594                 :             : 
     595                 :             : /* Disable -Wformat-diag; we want to be able to use pp_printf
     596                 :             :    for logging/dumping without complying with the rules for diagnostics.  */
     597                 :             : #if __GNUC__ >= 10
     598                 :             : #pragma GCC diagnostic ignored "-Wformat-diag"
     599                 :             : #endif
     600                 :             : 
     601                 :             : #if !ENABLE_ANALYZER
     602                 :             : extern void sorry_no_analyzer ();
     603                 :             : #endif /* #if !ENABLE_ANALYZER */
     604                 :             : 
     605                 :             : #endif /* GCC_ANALYZER_COMMON_H */
        

Generated by: LCOV version 2.1-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.