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: 2026-02-28 14:20:25 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         3937 : known_function_manager::known_function_manager (logger *logger)
      38         3937 : : log_user (logger)
      39              : {
      40         3937 :   memset (m_combined_fns_arr, 0, sizeof (m_combined_fns_arr));
      41         3937 : }
      42              : 
      43         3937 : known_function_manager::~known_function_manager ()
      44              : {
      45              :   /* Delete all owned kfs.  */
      46       652535 :   for (auto iter : m_map_id_to_kf)
      47       324299 :     delete iter.second;
      48       118755 :   for (auto iter : m_std_ns_map_id_to_kf)
      49        57409 :     delete iter.second;
      50      9094470 :   for (auto iter : m_combined_fns_arr)
      51      9090533 :     delete iter;
      52         3937 : }
      53              : 
      54              : void
      55       324299 : known_function_manager::add (const char *name,
      56              :                              std::unique_ptr<known_function> kf)
      57              : {
      58       324299 :   LOG_FUNC_1 (get_logger (), "registering %s", name);
      59       324299 :   tree id = get_identifier (name);
      60       324299 :   m_map_id_to_kf.put (id, kf.release ());
      61       324299 : }
      62              : 
      63              : void
      64        57409 : known_function_manager::add_std_ns (const char *name,
      65              :                              std::unique_ptr<known_function> kf)
      66              : {
      67        57409 :   LOG_FUNC_1 (get_logger (), "registering std::%s", name);
      68        57409 :   tree id = get_identifier (name);
      69        57409 :   m_std_ns_map_id_to_kf.put (id, kf.release ());
      70        57409 : }
      71              : 
      72              : void
      73       334323 : known_function_manager::add (enum built_in_function name,
      74              :                              std::unique_ptr<known_function> kf)
      75              : {
      76       334323 :   gcc_assert (name < END_BUILTINS);
      77       334323 :   delete m_combined_fns_arr[name];
      78       334323 :   m_combined_fns_arr[name] = kf.release ();
      79       334323 : }
      80              : 
      81              : void
      82        16885 : known_function_manager::add (enum internal_fn ifn,
      83              :                              std::unique_ptr<known_function> kf)
      84              : {
      85        16885 :   gcc_assert (ifn < IFN_LAST);
      86        16885 :   delete m_combined_fns_arr[ifn + int (END_BUILTINS)];
      87        16885 :   m_combined_fns_arr[ifn + int (END_BUILTINS)] = kf.release ();
      88        16885 : }
      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       345710 : known_function_manager::get_match (tree fndecl, const call_details &cd) const
     100              : {
     101              :   /* Look for a matching built-in.  */
     102       345710 :   if (fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
     103              :     {
     104       324034 :       if (const known_function *candidate
     105       162017 :           = get_normal_builtin (DECL_FUNCTION_CODE (fndecl)))
     106        22655 :         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       323055 :   if (is_std_function_p (fndecl))
     114              :     {
     115          330 :       if (tree identifier = DECL_NAME (fndecl))
     116          660 :         if (const known_function *candidate
     117          330 :               = get_by_identifier_in_std_ns (identifier))
     118          102 :           if (candidate->matches_call_types_p (cd))
     119              :             return candidate;
     120          228 :       return nullptr;
     121              :     }
     122              : 
     123       322725 :   if (DECL_CONTEXT (fndecl)
     124       322725 :       && TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL)
     125              :     return nullptr;
     126       319427 :   if (tree identifier = DECL_NAME (fndecl))
     127       319427 :     if (const known_function *candidate = get_by_identifier (identifier))
     128       212664 :       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         4813 : known_function_manager::get_internal_fn (enum internal_fn ifn) const
     138              : {
     139         4813 :   gcc_assert (ifn < IFN_LAST);
     140         4813 :   return m_combined_fns_arr[ifn + int (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       162017 : 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       162017 :   gcc_assert (name < END_BUILTINS);
     152       162017 :   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       319427 : known_function_manager::get_by_identifier (tree identifier) const
     167              : {
     168       319427 :   known_function_manager *mut_this = const_cast<known_function_manager *>(this);
     169       319427 :   known_function **slot = mut_this->m_map_id_to_kf.get (identifier);
     170       319427 :   if (slot)
     171       212664 :     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          330 : known_function_manager::get_by_identifier_in_std_ns (tree identifier) const
     182              : {
     183          330 :   known_function_manager *mut_this = const_cast<known_function_manager *>(this);
     184          330 :   known_function **slot = mut_this->m_std_ns_map_id_to_kf.get (identifier);
     185          330 :   if (slot)
     186          102 :     return *slot;
     187              :   else
     188              :     return nullptr;
     189              : }
     190              : 
     191              : 
     192              : } // namespace ana
     193              : 
     194              : #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.