]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/analyzer/known-function-manager.cc
analyzer: fix ICE on 'bind(INT_CST, ...)' [PR107783]
[thirdparty/gcc.git] / gcc / analyzer / known-function-manager.cc
CommitLineData
07e30160
DM
1/* Support for plugin-supplied behaviors of known functions.
2 Copyright (C) 2022 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
accece8c 22#define INCLUDE_MEMORY
07e30160
DM
23#include "system.h"
24#include "coretypes.h"
25#include "tree.h"
07e30160
DM
26#include "analyzer/analyzer.h"
27#include "diagnostic-core.h"
28#include "analyzer/analyzer-logging.h"
29#include "stringpool.h"
6bd31b33
DM
30#include "basic-block.h"
31#include "gimple.h"
07e30160 32#include "analyzer/known-function-manager.h"
6bd31b33 33#include "analyzer/region-model.h"
07e30160
DM
34
35#if ENABLE_ANALYZER
36
37namespace ana {
38
39/* class known_function_manager : public log_user. */
40
41known_function_manager::known_function_manager (logger *logger)
42: log_user (logger)
43{
6bd31b33 44 memset (m_combined_fns_arr, 0, sizeof (m_combined_fns_arr));
07e30160
DM
45}
46
47known_function_manager::~known_function_manager ()
48{
49 /* Delete all owned kfs. */
50 for (auto iter : m_map_id_to_kf)
51 delete iter.second;
6bd31b33
DM
52 for (auto iter : m_combined_fns_arr)
53 delete iter;
07e30160
DM
54}
55
56void
76dd2c4f
DM
57known_function_manager::add (const char *name,
58 std::unique_ptr<known_function> kf)
07e30160
DM
59{
60 LOG_FUNC_1 (get_logger (), "registering %s", name);
61 tree id = get_identifier (name);
76dd2c4f 62 m_map_id_to_kf.put (id, kf.release ());
07e30160
DM
63}
64
6bd31b33
DM
65void
66known_function_manager::add (enum built_in_function name,
67 std::unique_ptr<known_function> kf)
07e30160 68{
6bd31b33
DM
69 gcc_assert (name < END_BUILTINS);
70 delete m_combined_fns_arr[name];
71 m_combined_fns_arr[name] = kf.release ();
07e30160
DM
72}
73
6bd31b33
DM
74void
75known_function_manager::add (enum internal_fn ifn,
76 std::unique_ptr<known_function> kf)
77{
78 gcc_assert (ifn < IFN_LAST);
79 delete m_combined_fns_arr[ifn + END_BUILTINS];
80 m_combined_fns_arr[ifn + END_BUILTINS] = kf.release ();
81}
82
83/* Get any known_function for FNDECL for call CD.
84
85 The call must match all assumptions made by the known_function (such as
86 e.g. "argument 1's type must be a pointer type").
87
88 Return NULL if no known_function is found, or it does not match the
89 assumption(s). */
90
07e30160 91const known_function *
6bd31b33 92known_function_manager::get_match (tree fndecl, const call_details &cd) const
07e30160 93{
6bd31b33
DM
94 if (fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
95 {
96 if (const known_function *candidate
97 = get_normal_builtin (DECL_FUNCTION_CODE (fndecl)))
98 if (gimple_builtin_call_types_compatible_p (cd.get_call_stmt (),
99 fndecl))
100 return candidate;
101 }
07e30160 102 if (tree identifier = DECL_NAME (fndecl))
6bd31b33
DM
103 if (const known_function *candidate = get_by_identifier (identifier))
104 if (candidate->matches_call_types_p (cd))
105 return candidate;
07e30160
DM
106 return NULL;
107}
108
6bd31b33
DM
109/* Get any known_function for IFN, or NULL. */
110
111const known_function *
112known_function_manager::get_internal_fn (enum internal_fn ifn) const
113{
114 gcc_assert (ifn < IFN_LAST);
115 return m_combined_fns_arr[ifn + END_BUILTINS];
116}
117
118/* Get any known_function for NAME, without type-checking.
119 Return NULL if there isn't one. */
120
121const known_function *
122known_function_manager::get_normal_builtin (enum built_in_function name) const
123{
124 /* The numbers for built-in functions in enum combined_fn are the same as
125 for the built_in_function enum. */
126 gcc_assert (name < END_BUILTINS);
127 return m_combined_fns_arr[name];
128}
129
130/* Get any known_function matching IDENTIFIER, without type-checking.
131 Return NULL if there isn't one. */
132
133const known_function *
134known_function_manager::get_by_identifier (tree identifier) const
135{
136 known_function_manager *mut_this = const_cast<known_function_manager *>(this);
137 known_function **slot = mut_this->m_map_id_to_kf.get (identifier);
138 if (slot)
139 return *slot;
140 else
141 return NULL;
142}
143
07e30160
DM
144} // namespace ana
145
146#endif /* #if ENABLE_ANALYZER */