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