LCOV - code coverage report
Current view: top level - gcc/analyzer - sm.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 70.5 % 78 55
Test Date: 2025-07-12 13:27:34 Functions: 80.0 % 15 12
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-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                 :             : #define INCLUDE_LIST
      22                 :             : #include "analyzer/common.h"
      23                 :             : 
      24                 :             : #include "tree-diagnostic.h"
      25                 :             : 
      26                 :             : #include "analyzer/analyzer-logging.h"
      27                 :             : #include "analyzer/sm.h"
      28                 :             : #include "analyzer/call-string.h"
      29                 :             : #include "analyzer/program-point.h"
      30                 :             : #include "analyzer/store.h"
      31                 :             : #include "analyzer/svalue.h"
      32                 :             : #include "analyzer/program-state.h"
      33                 :             : #include "analyzer/pending-diagnostic.h"
      34                 :             : 
      35                 :             : #if ENABLE_ANALYZER
      36                 :             : 
      37                 :             : namespace ana {
      38                 :             : 
      39                 :             : /* Return true if VAR has pointer or reference type.  */
      40                 :             : 
      41                 :             : bool
      42                 :       36187 : any_pointer_p (tree var)
      43                 :             : {
      44                 :       36187 :   return POINTER_TYPE_P (TREE_TYPE (var));
      45                 :             : }
      46                 :             : 
      47                 :             : /* Return true if SVAL has pointer or reference type.  */
      48                 :             : 
      49                 :             : bool
      50                 :       55288 : any_pointer_p (const svalue *sval)
      51                 :             : {
      52                 :       55288 :   if (!sval->get_type ())
      53                 :             :     return false;
      54                 :       55288 :   return POINTER_TYPE_P (sval->get_type ());
      55                 :             : }
      56                 :             : 
      57                 :             : /* class state_machine::state.  */
      58                 :             : 
      59                 :             : /* Base implementation of dump_to_pp vfunc.  */
      60                 :             : 
      61                 :             : void
      62                 :         807 : state_machine::state::dump_to_pp (pretty_printer *pp) const
      63                 :             : {
      64                 :         807 :   pp_string (pp, m_name);
      65                 :         807 : }
      66                 :             : 
      67                 :             : /* Return a new json::string describing the state.  */
      68                 :             : 
      69                 :             : std::unique_ptr<json::value>
      70                 :          10 : state_machine::state::to_json () const
      71                 :             : {
      72                 :          10 :   pretty_printer pp;
      73                 :          10 :   pp_format_decoder (&pp) = default_tree_printer;
      74                 :          10 :   dump_to_pp (&pp);
      75                 :          10 :   return std::make_unique<json::string> (pp_formatted_text (&pp));
      76                 :          10 : }
      77                 :             : 
      78                 :             : /* class state_machine.  */
      79                 :             : 
      80                 :             : /* state_machine's ctor.  */
      81                 :             : 
      82                 :       23183 : state_machine::state_machine (const char *name, logger *logger)
      83                 :       23183 : : log_user (logger), m_name (name), m_next_state_id (0),
      84                 :       23183 :   m_start (add_state ("start"))
      85                 :             : {
      86                 :       23183 : }
      87                 :             : 
      88                 :             : /* Add a state with name NAME to this state_machine.
      89                 :             :    The string is required to outlive the state_machine.
      90                 :             : 
      91                 :             :    Return the state_t for the new state.  */
      92                 :             : 
      93                 :             : state_machine::state_t
      94                 :      135665 : state_machine::add_state (const char *name)
      95                 :             : {
      96                 :      135665 :   state *s = new state (name, alloc_state_id ());
      97                 :      135665 :   m_states.safe_push (s);
      98                 :      135665 :   return s;
      99                 :             : }
     100                 :             : 
     101                 :             : /* Get the state with name NAME, which must exist.
     102                 :             :    This is purely intended for use in selftests.  */
     103                 :             : 
     104                 :             : state_machine::state_t
     105                 :         188 : state_machine::get_state_by_name (const char *name) const
     106                 :             : {
     107                 :         188 :   unsigned i;
     108                 :         188 :   state *s;
     109                 :         376 :   FOR_EACH_VEC_ELT (m_states, i, s)
     110                 :         376 :     if (!strcmp (name, s->get_name ()))
     111                 :         188 :       return s;
     112                 :             :   /* Name not found.  */
     113                 :           0 :   gcc_unreachable ();
     114                 :             : }
     115                 :             : 
     116                 :             : /* Base implementation of state_machine::on_leak.  */
     117                 :             : 
     118                 :             : std::unique_ptr<pending_diagnostic>
     119                 :         437 : state_machine::on_leak (tree var ATTRIBUTE_UNUSED,
     120                 :             :                         const program_state *old_state ATTRIBUTE_UNUSED,
     121                 :             :                         const program_state *new_state ATTRIBUTE_UNUSED) const
     122                 :             : {
     123                 :         437 :   return nullptr;
     124                 :             : }
     125                 :             : 
     126                 :             : /* Dump a multiline representation of this state machine to PP.  */
     127                 :             : 
     128                 :             : void
     129                 :           0 : state_machine::dump_to_pp (pretty_printer *pp) const
     130                 :             : {
     131                 :           0 :   unsigned i;
     132                 :           0 :   state *s;
     133                 :           0 :   FOR_EACH_VEC_ELT (m_states, i, s)
     134                 :             :     {
     135                 :           0 :       pp_printf (pp, "  state %i: ", i);
     136                 :           0 :       s->dump_to_pp (pp);
     137                 :           0 :       pp_newline (pp);
     138                 :             :     }
     139                 :           0 : }
     140                 :             : 
     141                 :             : /* Return a new json::object of the form
     142                 :             :    {"name" : str,
     143                 :             :     "states" : [str]}.  */
     144                 :             : 
     145                 :             : std::unique_ptr<json::object>
     146                 :           0 : state_machine::to_json () const
     147                 :             : {
     148                 :           0 :   auto sm_obj = std::make_unique<json::object> ();
     149                 :             : 
     150                 :           0 :   sm_obj->set_string ("name", m_name);
     151                 :           0 :   {
     152                 :           0 :     auto states_arr = std::make_unique<json::array> ();
     153                 :           0 :     unsigned i;
     154                 :           0 :     state *s;
     155                 :           0 :     FOR_EACH_VEC_ELT (m_states, i, s)
     156                 :           0 :       states_arr->append (s->to_json ());
     157                 :           0 :     sm_obj->set ("states", std::move (states_arr));
     158                 :           0 :   }
     159                 :             : 
     160                 :           0 :   return sm_obj;
     161                 :             : }
     162                 :             : 
     163                 :             : void
     164                 :           0 : state_machine::add_state_to_state_graph (analyzer_state_graph &out_state_graph,
     165                 :             :                                          const svalue &sval,
     166                 :             :                                          state_machine::state_t state) const
     167                 :             : {
     168                 :             :   // no-op
     169                 :           0 : }
     170                 :             : 
     171                 :             : void
     172                 :         196 : state_machine::add_global_state_to_state_graph (analyzer_state_graph &out_state_graph,
     173                 :             :                                                 state_machine::state_t state) const
     174                 :             : {
     175                 :             :   // no-op
     176                 :         196 : }
     177                 :             : 
     178                 :             : /* class sm_context.  */
     179                 :             : 
     180                 :             : const region_model *
     181                 :      269042 : sm_context::get_old_region_model () const
     182                 :             : {
     183                 :      269042 :   if (const program_state *old_state = get_old_program_state ())
     184                 :      269042 :     return old_state->m_region_model;
     185                 :             :   else
     186                 :             :     return nullptr;
     187                 :             : }
     188                 :             : 
     189                 :             : /* Create instances of the various state machines, each using LOGGER,
     190                 :             :    returning a vector of them.  */
     191                 :             : 
     192                 :             : std::vector<std::unique_ptr<state_machine>>
     193                 :        3308 : make_checkers (logger *logger)
     194                 :             : {
     195                 :             :   /* Start with a list so that we can filter it.  */
     196                 :        3308 :   std::list<std::unique_ptr<state_machine>> out;
     197                 :        3308 :   out.push_back (make_malloc_state_machine (logger));
     198                 :        3308 :   out.push_back (make_fileptr_state_machine (logger));
     199                 :        3308 :   out.push_back (make_fd_state_machine (logger));
     200                 :        3308 :   out.push_back (make_taint_state_machine (logger));
     201                 :        3308 :   out.push_back (make_sensitive_state_machine (logger));
     202                 :        3308 :   out.push_back (make_signal_state_machine (logger));
     203                 :        3308 :   out.push_back (make_va_list_state_machine (logger));
     204                 :             : 
     205                 :             :   /* We only attempt to run the pattern tests if it might have been manually
     206                 :             :      enabled (for DejaGnu purposes).  */
     207                 :        3308 :   if (flag_analyzer_checker)
     208                 :          10 :     out.push_back (make_pattern_test_state_machine (logger));
     209                 :             : 
     210                 :        3308 :   if (flag_analyzer_checker)
     211                 :             :     {
     212                 :          10 :       out.remove_if ([] (auto &sm)
     213                 :             :                      {
     214                 :          80 :                        return 0 != strcmp (flag_analyzer_checker,
     215                 :          80 :                                            sm->get_name ());
     216                 :             :                      });
     217                 :             :     }
     218                 :             : 
     219                 :        3308 :   std::vector<std::unique_ptr<state_machine>> out_vec;
     220                 :       26404 :   for (auto &iter: out)
     221                 :       23096 :     out_vec.push_back (std::move (iter));
     222                 :             : 
     223                 :        3308 :   return out_vec;
     224                 :        3308 : }
     225                 :             : 
     226                 :             : } // namespace ana
     227                 :             : 
     228                 :             : #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.