LCOV - code coverage report
Current view: top level - gcc/analyzer - sm.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 70.6 % 68 48
Test Date: 2024-04-20 14:03:02 Functions: 83.3 % 12 10
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Modeling API uses and misuses via state machines.
       2                 :             :    Copyright (C) 2019-2024 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                 :             : #include "config.h"
      22                 :             : #define INCLUDE_MEMORY
      23                 :             : #include "system.h"
      24                 :             : #include "coretypes.h"
      25                 :             : #include "tree.h"
      26                 :             : #include "function.h"
      27                 :             : #include "basic-block.h"
      28                 :             : #include "gimple.h"
      29                 :             : #include "options.h"
      30                 :             : #include "function.h"
      31                 :             : #include "diagnostic-core.h"
      32                 :             : #include "pretty-print.h"
      33                 :             : #include "diagnostic.h"
      34                 :             : #include "tree-diagnostic.h"
      35                 :             : #include "analyzer/analyzer.h"
      36                 :             : #include "analyzer/analyzer-logging.h"
      37                 :             : #include "analyzer/sm.h"
      38                 :             : #include "analyzer/call-string.h"
      39                 :             : #include "analyzer/program-point.h"
      40                 :             : #include "analyzer/store.h"
      41                 :             : #include "analyzer/svalue.h"
      42                 :             : #include "analyzer/program-state.h"
      43                 :             : #include "analyzer/pending-diagnostic.h"
      44                 :             : 
      45                 :             : #if ENABLE_ANALYZER
      46                 :             : 
      47                 :             : namespace ana {
      48                 :             : 
      49                 :             : /* Return true if VAR has pointer or reference type.  */
      50                 :             : 
      51                 :             : bool
      52                 :       42835 : any_pointer_p (tree var)
      53                 :             : {
      54                 :       42835 :   return POINTER_TYPE_P (TREE_TYPE (var));
      55                 :             : }
      56                 :             : 
      57                 :             : /* Return true if SVAL has pointer or reference type.  */
      58                 :             : 
      59                 :             : bool
      60                 :       64878 : any_pointer_p (const svalue *sval)
      61                 :             : {
      62                 :       64878 :   if (!sval->get_type ())
      63                 :             :     return false;
      64                 :       64878 :   return POINTER_TYPE_P (sval->get_type ());
      65                 :             : }
      66                 :             : 
      67                 :             : /* class state_machine::state.  */
      68                 :             : 
      69                 :             : /* Base implementation of dump_to_pp vfunc.  */
      70                 :             : 
      71                 :             : void
      72                 :         976 : state_machine::state::dump_to_pp (pretty_printer *pp) const
      73                 :             : {
      74                 :         976 :   pp_string (pp, m_name);
      75                 :         976 : }
      76                 :             : 
      77                 :             : /* Return a new json::string describing the state.  */
      78                 :             : 
      79                 :             : json::value *
      80                 :           5 : state_machine::state::to_json () const
      81                 :             : {
      82                 :           5 :   pretty_printer pp;
      83                 :           5 :   pp_format_decoder (&pp) = default_tree_printer;
      84                 :           5 :   dump_to_pp (&pp);
      85                 :           5 :   return new json::string (pp_formatted_text (&pp));
      86                 :           5 : }
      87                 :             : 
      88                 :             : /* class state_machine.  */
      89                 :             : 
      90                 :             : /* state_machine's ctor.  */
      91                 :             : 
      92                 :       26192 : state_machine::state_machine (const char *name, logger *logger)
      93                 :       26192 : : log_user (logger), m_name (name), m_next_state_id (0),
      94                 :       26192 :   m_start (add_state ("start"))
      95                 :             : {
      96                 :       26192 : }
      97                 :             : 
      98                 :             : /* Add a state with name NAME to this state_machine.
      99                 :             :    The string is required to outlive the state_machine.
     100                 :             : 
     101                 :             :    Return the state_t for the new state.  */
     102                 :             : 
     103                 :             : state_machine::state_t
     104                 :      153260 : state_machine::add_state (const char *name)
     105                 :             : {
     106                 :      153260 :   state *s = new state (name, alloc_state_id ());
     107                 :      153260 :   m_states.safe_push (s);
     108                 :      153260 :   return s;
     109                 :             : }
     110                 :             : 
     111                 :             : /* Get the state with name NAME, which must exist.
     112                 :             :    This is purely intended for use in selftests.  */
     113                 :             : 
     114                 :             : state_machine::state_t
     115                 :         209 : state_machine::get_state_by_name (const char *name) const
     116                 :             : {
     117                 :         209 :   unsigned i;
     118                 :         209 :   state *s;
     119                 :         418 :   FOR_EACH_VEC_ELT (m_states, i, s)
     120                 :         418 :     if (!strcmp (name, s->get_name ()))
     121                 :         209 :       return s;
     122                 :             :   /* Name not found.  */
     123                 :           0 :   gcc_unreachable ();
     124                 :             : }
     125                 :             : 
     126                 :             : /* Base implementation of state_machine::on_leak.  */
     127                 :             : 
     128                 :             : std::unique_ptr<pending_diagnostic>
     129                 :         465 : state_machine::on_leak (tree var ATTRIBUTE_UNUSED) const
     130                 :             : {
     131                 :         465 :   return NULL;
     132                 :             : }
     133                 :             : 
     134                 :             : /* Dump a multiline representation of this state machine to PP.  */
     135                 :             : 
     136                 :             : void
     137                 :           0 : state_machine::dump_to_pp (pretty_printer *pp) const
     138                 :             : {
     139                 :           0 :   unsigned i;
     140                 :           0 :   state *s;
     141                 :           0 :   FOR_EACH_VEC_ELT (m_states, i, s)
     142                 :             :     {
     143                 :           0 :       pp_printf (pp, "  state %i: ", i);
     144                 :           0 :       s->dump_to_pp (pp);
     145                 :           0 :       pp_newline (pp);
     146                 :             :     }
     147                 :           0 : }
     148                 :             : 
     149                 :             : /* Return a new json::object of the form
     150                 :             :    {"name" : str,
     151                 :             :     "states" : [str]}.  */
     152                 :             : 
     153                 :             : json::object *
     154                 :           0 : state_machine::to_json () const
     155                 :             : {
     156                 :           0 :   json::object *sm_obj = new json::object ();
     157                 :             : 
     158                 :           0 :   sm_obj->set ("name", new json::string (m_name));
     159                 :           0 :   {
     160                 :           0 :     json::array *states_arr = new json::array ();
     161                 :           0 :     unsigned i;
     162                 :           0 :     state *s;
     163                 :           0 :     FOR_EACH_VEC_ELT (m_states, i, s)
     164                 :           0 :       states_arr->append (s->to_json ());
     165                 :           0 :     sm_obj->set ("states", states_arr);
     166                 :             :   }
     167                 :             : 
     168                 :           0 :   return sm_obj;
     169                 :             : }
     170                 :             : 
     171                 :             : /* class sm_context.  */
     172                 :             : 
     173                 :             : const region_model *
     174                 :      312222 : sm_context::get_old_region_model () const
     175                 :             : {
     176                 :      312222 :   if (const program_state *old_state = get_old_program_state ())
     177                 :      312222 :     return old_state->m_region_model;
     178                 :             :   else
     179                 :             :     return NULL;
     180                 :             : }
     181                 :             : 
     182                 :             : /* Create instances of the various state machines, each using LOGGER,
     183                 :             :    and populate OUT with them.  */
     184                 :             : 
     185                 :             : void
     186                 :        3737 : make_checkers (auto_delete_vec <state_machine> &out, logger *logger)
     187                 :             : {
     188                 :        3737 :   out.safe_push (make_malloc_state_machine (logger));
     189                 :        3737 :   out.safe_push (make_fileptr_state_machine (logger));
     190                 :        3737 :   out.safe_push (make_fd_state_machine (logger));
     191                 :        3737 :   out.safe_push (make_taint_state_machine (logger));
     192                 :        3737 :   out.safe_push (make_sensitive_state_machine (logger));
     193                 :        3737 :   out.safe_push (make_signal_state_machine (logger));
     194                 :        3737 :   out.safe_push (make_va_list_state_machine (logger));
     195                 :             : 
     196                 :             :   /* We only attempt to run the pattern tests if it might have been manually
     197                 :             :      enabled (for DejaGnu purposes).  */
     198                 :        3737 :   if (flag_analyzer_checker)
     199                 :          16 :     out.safe_push (make_pattern_test_state_machine (logger));
     200                 :             : 
     201                 :        3737 :   if (flag_analyzer_checker)
     202                 :             :     {
     203                 :          16 :       unsigned read_index, write_index;
     204                 :          16 :       state_machine **sm;
     205                 :             : 
     206                 :             :       /* TODO: this leaks the machines
     207                 :             :          Would be nice to log the things that were removed.  */
     208                 :         160 :       VEC_ORDERED_REMOVE_IF (out, read_index, write_index, sm,
     209                 :             :                              0 != strcmp (flag_analyzer_checker,
     210                 :             :                                           (*sm)->get_name ()));
     211                 :             :     }
     212                 :        3737 : }
     213                 :             : 
     214                 :             : } // namespace ana
     215                 :             : 
     216                 :             : #endif /* #if ENABLE_ANALYZER */
        

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.