LCOV - code coverage report
Current view: top level - gcc/analyzer - known-function-manager.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 97.1 % 68 66
Test Date: 2026-08-22 16:33:35 Functions: 91.7 % 12 11
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Support for plugin-supplied behaviors of known functions.
       2              :    Copyright (C) 2022-2026 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         4061 : known_function_manager::known_function_manager (logger *logger)
      38         4061 : : log_user (logger)
      39              : {
      40         4061 :   memset (m_combined_fns_arr, 0, sizeof (m_combined_fns_arr));
      41         4061 : }
      42              : 
      43         4061 : known_function_manager::~known_function_manager ()
      44              : {
      45              :   /* Delete all owned kfs.  */
      46       385777 :   for (auto iter : m_map_id_to_kf)
      47       381716 :     delete iter.second;
      48        74081 :   for (auto iter : m_std_ns_map_id_to_kf)
      49        70020 :     delete iter.second;
      50      9502740 :   for (auto iter : m_combined_fns_arr)
      51      9498679 :     delete iter;
      52         4061 : }
      53              : 
      54              : void
      55       381716 : known_function_manager::add (const char *name,
      56              :                              std::unique_ptr<known_function> kf)
      57              : {
      58       381716 :   LOG_FUNC_1 (get_logger (), "registering %s", name);
      59       381716 :   tree id = get_identifier (name);
      60       381716 :   m_map_id_to_kf.put (id, kf.release ());
      61       381716 : }
      62              : 
      63              : void
      64        70020 : known_function_manager::add_std_ns (const char *name,
      65              :                              std::unique_ptr<known_function> kf)
      66              : {
      67        70020 :   LOG_FUNC_1 (get_logger (), "registering std::%s", name);
      68        70020 :   tree id = get_identifier (name);
      69        70020 :   m_std_ns_map_id_to_kf.put (id, kf.release ());
      70        70020 : }
      71              : 
      72              : void
      73       350100 : known_function_manager::add (enum built_in_function name,
      74              :                              std::unique_ptr<known_function> kf)
      75              : {
      76       350100 :   gcc_assert (name < END_BUILTINS);
      77       350100 :   delete m_combined_fns_arr[name];
      78       350100 :   m_combined_fns_arr[name] = kf.release ();
      79       350100 : }
      80              : 
      81              : void
      82        17505 : known_function_manager::add (enum internal_fn ifn,
      83              :                              std::unique_ptr<known_function> kf)
      84              : {
      85        17505 :   gcc_assert (ifn < IFN_LAST);
      86        17505 :   delete m_combined_fns_arr[ifn + int (END_BUILTINS)];
      87        17505 :   m_combined_fns_arr[ifn + int (END_BUILTINS)] = kf.release ();
      88        17505 : }
      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       370778 : known_function_manager::get_match (tree fndecl, const call_details &cd) const
     100              : {
     101              :   /* Look for a matching built-in.  */
     102       370778 :   if (fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
     103              :     {
     104       337798 :       if (const known_function *candidate
     105       168899 :           = get_normal_builtin (DECL_FUNCTION_CODE (fndecl)))
     106        23907 :         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       346871 :   if (is_std_function_p (fndecl))
     114              :     {
     115         1198 :       if (tree identifier = DECL_NAME (fndecl))
     116         2396 :         if (const known_function *candidate
     117         1198 :               = get_by_identifier_in_std_ns (identifier))
     118          120 :           if (candidate->matches_call_types_p (cd))
     119              :             return candidate;
     120         1078 :       return nullptr;
     121              :     }
     122              : 
     123              :   /* Only match functions declared at global scope, or within namespace
     124              :      __cxxabiv1 (e.g. __dynamic_cast).  */
     125       345673 :   if (!is_cxxabi_function_p (fndecl))
     126       345010 :     if (DECL_CONTEXT (fndecl)
     127       345010 :         && TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL)
     128              :       return nullptr;
     129              : 
     130       340107 :   if (tree identifier = DECL_NAME (fndecl))
     131       340107 :     if (const known_function *candidate = get_by_identifier (identifier))
     132       229740 :       if (candidate->matches_call_types_p (cd))
     133       229172 :         return candidate;
     134              : 
     135              :   return nullptr;
     136              : }
     137              : 
     138              : /* Get any known_function for IFN, or nullptr.  */
     139              : 
     140              : const known_function *
     141         4923 : known_function_manager::get_internal_fn (enum internal_fn ifn) const
     142              : {
     143         4923 :   gcc_assert (ifn < IFN_LAST);
     144         4923 :   return m_combined_fns_arr[ifn + int (END_BUILTINS)];
     145              : }
     146              : 
     147              : /* Get any known_function for NAME, without type-checking.
     148              :    Return nullptr if there isn't one.  */
     149              : 
     150              : const known_function *
     151       168899 : known_function_manager::get_normal_builtin (enum built_in_function name) const
     152              : {
     153              :   /* The numbers for built-in functions in enum combined_fn are the same as
     154              :      for the built_in_function enum.  */
     155       168899 :   gcc_assert (name < END_BUILTINS);
     156       168899 :   return m_combined_fns_arr[name];
     157              : }
     158              : 
     159              : const known_function *
     160            0 : known_function_manager::
     161              : get_normal_builtin (const builtin_known_function *builtin_kf) const
     162              : {
     163            0 :   return get_normal_builtin (builtin_kf->builtin_code ());
     164              : }
     165              : 
     166              : /* Get any known_function matching IDENTIFIER, without type-checking.
     167              :    Return nullptr if there isn't one.  */
     168              : 
     169              : const known_function *
     170       340107 : known_function_manager::get_by_identifier (tree identifier) const
     171              : {
     172       340107 :   known_function_manager *mut_this = const_cast<known_function_manager *>(this);
     173       340107 :   known_function **slot = mut_this->m_map_id_to_kf.get (identifier);
     174       340107 :   if (slot)
     175       229740 :     return *slot;
     176              :   else
     177              :     return nullptr;
     178              : }
     179              : 
     180              : /* Get any known_function in C++ std:: namespace matching IDENTIFIER, without
     181              :    type-checking.
     182              :    Return nullptr if there isn't one.  */
     183              : 
     184              : const known_function *
     185         1198 : known_function_manager::get_by_identifier_in_std_ns (tree identifier) const
     186              : {
     187         1198 :   known_function_manager *mut_this = const_cast<known_function_manager *>(this);
     188         1198 :   known_function **slot = mut_this->m_std_ns_map_id_to_kf.get (identifier);
     189         1198 :   if (slot)
     190          120 :     return *slot;
     191              :   else
     192              :     return nullptr;
     193              : }
     194              : 
     195              : 
     196              : } // namespace ana
     197              : 
     198              : #endif /* #if ENABLE_ANALYZER */
        

Generated by: LCOV version 2.4-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.