LCOV - code coverage report
Current view: top level - gcc/analyzer - known-function-manager.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 97.0 % 66 64
Test Date: 2024-12-21 13:15:12 Functions: 91.7 % 12 11
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Support for plugin-supplied behaviors of known functions.
       2                 :             :    Copyright (C) 2022-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 "analyzer/analyzer.h"
      27                 :             : #include "diagnostic-core.h"
      28                 :             : #include "analyzer/analyzer-logging.h"
      29                 :             : #include "stringpool.h"
      30                 :             : #include "basic-block.h"
      31                 :             : #include "gimple.h"
      32                 :             : #include "analyzer/known-function-manager.h"
      33                 :             : #include "analyzer/region-model.h"
      34                 :             : #include "analyzer/call-details.h"
      35                 :             : 
      36                 :             : #if ENABLE_ANALYZER
      37                 :             : 
      38                 :             : namespace ana {
      39                 :             : 
      40                 :             : /* class known_function_manager : public log_user.  */
      41                 :             : 
      42                 :        3771 : known_function_manager::known_function_manager (logger *logger)
      43                 :        3771 : : log_user (logger)
      44                 :             : {
      45                 :        3771 :   memset (m_combined_fns_arr, 0, sizeof (m_combined_fns_arr));
      46                 :        3771 : }
      47                 :             : 
      48                 :        3771 : known_function_manager::~known_function_manager ()
      49                 :             : {
      50                 :             :   /* Delete all owned kfs.  */
      51                 :      554213 :   for (auto iter : m_map_id_to_kf)
      52                 :      275221 :     delete iter.second;
      53                 :      112537 :   for (auto iter : m_std_ns_map_id_to_kf)
      54                 :       54383 :     delete iter.second;
      55                 :     8367849 :   for (auto iter : m_combined_fns_arr)
      56                 :     8364078 :     delete iter;
      57                 :        3771 : }
      58                 :             : 
      59                 :             : void
      60                 :      275221 : known_function_manager::add (const char *name,
      61                 :             :                              std::unique_ptr<known_function> kf)
      62                 :             : {
      63                 :      275221 :   LOG_FUNC_1 (get_logger (), "registering %s", name);
      64                 :      275221 :   tree id = get_identifier (name);
      65                 :      275221 :   m_map_id_to_kf.put (id, kf.release ());
      66                 :      275221 : }
      67                 :             : 
      68                 :             : void
      69                 :       54383 : known_function_manager::add_std_ns (const char *name,
      70                 :             :                              std::unique_ptr<known_function> kf)
      71                 :             : {
      72                 :       54383 :   LOG_FUNC_1 (get_logger (), "registering std::%s", name);
      73                 :       54383 :   tree id = get_identifier (name);
      74                 :       54383 :   m_std_ns_map_id_to_kf.put (id, kf.release ());
      75                 :       54383 : }
      76                 :             : 
      77                 :             : void
      78                 :      550228 : known_function_manager::add (enum built_in_function name,
      79                 :             :                              std::unique_ptr<known_function> kf)
      80                 :             : {
      81                 :      550228 :   gcc_assert (name < END_BUILTINS);
      82                 :      550228 :   delete m_combined_fns_arr[name];
      83                 :      550228 :   m_combined_fns_arr[name] = kf.release ();
      84                 :      550228 : }
      85                 :             : 
      86                 :             : void
      87                 :       12796 : known_function_manager::add (enum internal_fn ifn,
      88                 :             :                              std::unique_ptr<known_function> kf)
      89                 :             : {
      90                 :       12796 :   gcc_assert (ifn < IFN_LAST);
      91                 :       12796 :   delete m_combined_fns_arr[ifn + END_BUILTINS];
      92                 :       12796 :   m_combined_fns_arr[ifn + END_BUILTINS] = kf.release ();
      93                 :       12796 : }
      94                 :             : 
      95                 :             : /* Get any known_function for FNDECL for call CD.
      96                 :             : 
      97                 :             :    The call must match all assumptions made by the known_function (such as
      98                 :             :    e.g. "argument 1's type must be a pointer type").
      99                 :             : 
     100                 :             :    Return NULL if no known_function is found, or it does not match the
     101                 :             :    assumption(s).  */
     102                 :             : 
     103                 :             : const known_function *
     104                 :      354632 : known_function_manager::get_match (tree fndecl, const call_details &cd) const
     105                 :             : {
     106                 :             :   /* Look for a matching built-in.  */
     107                 :      354632 :   if (fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
     108                 :             :     {
     109                 :      292624 :       if (const known_function *candidate
     110                 :      146312 :           = get_normal_builtin (DECL_FUNCTION_CODE (fndecl)))
     111                 :       19019 :         if (gimple_builtin_call_types_compatible_p (cd.get_call_stmt (),
     112                 :             :                                                     fndecl))
     113                 :             :           return candidate;
     114                 :             :     }
     115                 :             : 
     116                 :             :   /* Look for a match by name.  */
     117                 :             : 
     118                 :      335613 :   if (is_std_function_p (fndecl))
     119                 :             :     {
     120                 :         108 :       if (tree identifier = DECL_NAME (fndecl))
     121                 :         216 :         if (const known_function *candidate
     122                 :         108 :               = get_by_identifier_in_std_ns (identifier))
     123                 :          90 :           if (candidate->matches_call_types_p (cd))
     124                 :             :             return candidate;
     125                 :          18 :       return nullptr;
     126                 :             :     }
     127                 :             : 
     128                 :      335505 :   if (DECL_CONTEXT (fndecl)
     129                 :      335505 :       && TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL)
     130                 :             :     return NULL;
     131                 :      329821 :   if (tree identifier = DECL_NAME (fndecl))
     132                 :      329821 :     if (const known_function *candidate = get_by_identifier (identifier))
     133                 :      192739 :       if (candidate->matches_call_types_p (cd))
     134                 :             :         return candidate;
     135                 :             : 
     136                 :             :   return NULL;
     137                 :             : }
     138                 :             : 
     139                 :             : /* Get any known_function for IFN, or NULL.  */
     140                 :             : 
     141                 :             : const known_function *
     142                 :        1327 : known_function_manager::get_internal_fn (enum internal_fn ifn) const
     143                 :             : {
     144                 :        1327 :   gcc_assert (ifn < IFN_LAST);
     145                 :        1327 :   return m_combined_fns_arr[ifn + END_BUILTINS];
     146                 :             : }
     147                 :             : 
     148                 :             : /* Get any known_function for NAME, without type-checking.
     149                 :             :    Return NULL if there isn't one.  */
     150                 :             : 
     151                 :             : const known_function *
     152                 :      146312 : known_function_manager::get_normal_builtin (enum built_in_function name) const
     153                 :             : {
     154                 :             :   /* The numbers for built-in functions in enum combined_fn are the same as
     155                 :             :      for the built_in_function enum.  */
     156                 :      146312 :   gcc_assert (name < END_BUILTINS);
     157                 :      146312 :   return m_combined_fns_arr[name];
     158                 :             : }
     159                 :             : 
     160                 :             : const known_function *
     161                 :           0 : known_function_manager::
     162                 :             : get_normal_builtin (const builtin_known_function *builtin_kf) const
     163                 :             : {
     164                 :           0 :   return get_normal_builtin (builtin_kf->builtin_code ());
     165                 :             : }
     166                 :             : 
     167                 :             : /* Get any known_function matching IDENTIFIER, without type-checking.
     168                 :             :    Return NULL if there isn't one.  */
     169                 :             : 
     170                 :             : const known_function *
     171                 :      329821 : known_function_manager::get_by_identifier (tree identifier) const
     172                 :             : {
     173                 :      329821 :   known_function_manager *mut_this = const_cast<known_function_manager *>(this);
     174                 :      329821 :   known_function **slot = mut_this->m_map_id_to_kf.get (identifier);
     175                 :      329821 :   if (slot)
     176                 :      192739 :     return *slot;
     177                 :             :   else
     178                 :             :     return NULL;
     179                 :             : }
     180                 :             : 
     181                 :             : /* Get any known_function in C++ std:: namespace matching IDENTIFIER, without
     182                 :             :    type-checking.
     183                 :             :    Return nullptr if there isn't one.  */
     184                 :             : 
     185                 :             : const known_function *
     186                 :         108 : known_function_manager::get_by_identifier_in_std_ns (tree identifier) const
     187                 :             : {
     188                 :         108 :   known_function_manager *mut_this = const_cast<known_function_manager *>(this);
     189                 :         108 :   known_function **slot = mut_this->m_std_ns_map_id_to_kf.get (identifier);
     190                 :         108 :   if (slot)
     191                 :          90 :     return *slot;
     192                 :             :   else
     193                 :             :     return nullptr;
     194                 :             : }
     195                 :             : 
     196                 :             : 
     197                 :             : } // namespace ana
     198                 :             : 
     199                 :             : #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.