LCOV - code coverage report
Current view: top level - gcc/analyzer - sm.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 69.6 % 69 48
Test Date: 2024-11-30 13:30: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_VECTOR
      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                 :             : #include "make-unique.h"
      45                 :             : 
      46                 :             : #if ENABLE_ANALYZER
      47                 :             : 
      48                 :             : namespace ana {
      49                 :             : 
      50                 :             : /* Return true if VAR has pointer or reference type.  */
      51                 :             : 
      52                 :             : bool
      53                 :       35864 : any_pointer_p (tree var)
      54                 :             : {
      55                 :       35864 :   return POINTER_TYPE_P (TREE_TYPE (var));
      56                 :             : }
      57                 :             : 
      58                 :             : /* Return true if SVAL has pointer or reference type.  */
      59                 :             : 
      60                 :             : bool
      61                 :       55154 : any_pointer_p (const svalue *sval)
      62                 :             : {
      63                 :       55154 :   if (!sval->get_type ())
      64                 :             :     return false;
      65                 :       55154 :   return POINTER_TYPE_P (sval->get_type ());
      66                 :             : }
      67                 :             : 
      68                 :             : /* class state_machine::state.  */
      69                 :             : 
      70                 :             : /* Base implementation of dump_to_pp vfunc.  */
      71                 :             : 
      72                 :             : void
      73                 :         806 : state_machine::state::dump_to_pp (pretty_printer *pp) const
      74                 :             : {
      75                 :         806 :   pp_string (pp, m_name);
      76                 :         806 : }
      77                 :             : 
      78                 :             : /* Return a new json::string describing the state.  */
      79                 :             : 
      80                 :             : std::unique_ptr<json::value>
      81                 :           9 : state_machine::state::to_json () const
      82                 :             : {
      83                 :           9 :   pretty_printer pp;
      84                 :           9 :   pp_format_decoder (&pp) = default_tree_printer;
      85                 :           9 :   dump_to_pp (&pp);
      86                 :           9 :   return ::make_unique<json::string> (pp_formatted_text (&pp));
      87                 :           9 : }
      88                 :             : 
      89                 :             : /* class state_machine.  */
      90                 :             : 
      91                 :             : /* state_machine's ctor.  */
      92                 :             : 
      93                 :       22406 : state_machine::state_machine (const char *name, logger *logger)
      94                 :       22406 : : log_user (logger), m_name (name), m_next_state_id (0),
      95                 :       22406 :   m_start (add_state ("start"))
      96                 :             : {
      97                 :       22406 : }
      98                 :             : 
      99                 :             : /* Add a state with name NAME to this state_machine.
     100                 :             :    The string is required to outlive the state_machine.
     101                 :             : 
     102                 :             :    Return the state_t for the new state.  */
     103                 :             : 
     104                 :             : state_machine::state_t
     105                 :      131114 : state_machine::add_state (const char *name)
     106                 :             : {
     107                 :      131114 :   state *s = new state (name, alloc_state_id ());
     108                 :      131114 :   m_states.safe_push (s);
     109                 :      131114 :   return s;
     110                 :             : }
     111                 :             : 
     112                 :             : /* Get the state with name NAME, which must exist.
     113                 :             :    This is purely intended for use in selftests.  */
     114                 :             : 
     115                 :             : state_machine::state_t
     116                 :         188 : state_machine::get_state_by_name (const char *name) const
     117                 :             : {
     118                 :         188 :   unsigned i;
     119                 :         188 :   state *s;
     120                 :         376 :   FOR_EACH_VEC_ELT (m_states, i, s)
     121                 :         376 :     if (!strcmp (name, s->get_name ()))
     122                 :         188 :       return s;
     123                 :             :   /* Name not found.  */
     124                 :           0 :   gcc_unreachable ();
     125                 :             : }
     126                 :             : 
     127                 :             : /* Base implementation of state_machine::on_leak.  */
     128                 :             : 
     129                 :             : std::unique_ptr<pending_diagnostic>
     130                 :         437 : state_machine::on_leak (tree var ATTRIBUTE_UNUSED) const
     131                 :             : {
     132                 :         437 :   return NULL;
     133                 :             : }
     134                 :             : 
     135                 :             : /* Dump a multiline representation of this state machine to PP.  */
     136                 :             : 
     137                 :             : void
     138                 :           0 : state_machine::dump_to_pp (pretty_printer *pp) const
     139                 :             : {
     140                 :           0 :   unsigned i;
     141                 :           0 :   state *s;
     142                 :           0 :   FOR_EACH_VEC_ELT (m_states, i, s)
     143                 :             :     {
     144                 :           0 :       pp_printf (pp, "  state %i: ", i);
     145                 :           0 :       s->dump_to_pp (pp);
     146                 :           0 :       pp_newline (pp);
     147                 :             :     }
     148                 :           0 : }
     149                 :             : 
     150                 :             : /* Return a new json::object of the form
     151                 :             :    {"name" : str,
     152                 :             :     "states" : [str]}.  */
     153                 :             : 
     154                 :             : std::unique_ptr<json::object>
     155                 :           0 : state_machine::to_json () const
     156                 :             : {
     157                 :           0 :   auto sm_obj = ::make_unique<json::object> ();
     158                 :             : 
     159                 :           0 :   sm_obj->set_string ("name", m_name);
     160                 :           0 :   {
     161                 :           0 :     auto states_arr = ::make_unique<json::array> ();
     162                 :           0 :     unsigned i;
     163                 :           0 :     state *s;
     164                 :           0 :     FOR_EACH_VEC_ELT (m_states, i, s)
     165                 :           0 :       states_arr->append (s->to_json ());
     166                 :           0 :     sm_obj->set ("states", std::move (states_arr));
     167                 :           0 :   }
     168                 :             : 
     169                 :           0 :   return sm_obj;
     170                 :             : }
     171                 :             : 
     172                 :             : /* class sm_context.  */
     173                 :             : 
     174                 :             : const region_model *
     175                 :      260497 : sm_context::get_old_region_model () const
     176                 :             : {
     177                 :      260497 :   if (const program_state *old_state = get_old_program_state ())
     178                 :      260497 :     return old_state->m_region_model;
     179                 :             :   else
     180                 :             :     return NULL;
     181                 :             : }
     182                 :             : 
     183                 :             : /* Create instances of the various state machines, each using LOGGER,
     184                 :             :    and populate OUT with them.  */
     185                 :             : 
     186                 :             : void
     187                 :        3197 : make_checkers (auto_delete_vec <state_machine> &out, logger *logger)
     188                 :             : {
     189                 :        3197 :   out.safe_push (make_malloc_state_machine (logger));
     190                 :        3197 :   out.safe_push (make_fileptr_state_machine (logger));
     191                 :        3197 :   out.safe_push (make_fd_state_machine (logger));
     192                 :        3197 :   out.safe_push (make_taint_state_machine (logger));
     193                 :        3197 :   out.safe_push (make_sensitive_state_machine (logger));
     194                 :        3197 :   out.safe_push (make_signal_state_machine (logger));
     195                 :        3197 :   out.safe_push (make_va_list_state_machine (logger));
     196                 :             : 
     197                 :             :   /* We only attempt to run the pattern tests if it might have been manually
     198                 :             :      enabled (for DejaGnu purposes).  */
     199                 :        3197 :   if (flag_analyzer_checker)
     200                 :          10 :     out.safe_push (make_pattern_test_state_machine (logger));
     201                 :             : 
     202                 :        3197 :   if (flag_analyzer_checker)
     203                 :             :     {
     204                 :          10 :       unsigned read_index, write_index;
     205                 :          10 :       state_machine **sm;
     206                 :             : 
     207                 :             :       /* TODO: this leaks the machines
     208                 :             :          Would be nice to log the things that were removed.  */
     209                 :          90 :       VEC_ORDERED_REMOVE_IF (out, read_index, write_index, sm,
     210                 :             :                              0 != strcmp (flag_analyzer_checker,
     211                 :             :                                           (*sm)->get_name ()));
     212                 :             :     }
     213                 :        3197 : }
     214                 :             : 
     215                 :             : } // namespace ana
     216                 :             : 
     217                 :             : #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.