]>
Commit | Line | Data |
---|---|---|
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 | ||
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" | |
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 | ||
37 | namespace ana { | |
38 | ||
39 | /* class known_function_manager : public log_user. */ | |
40 | ||
41 | known_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 | ||
47 | known_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 | ||
56 | void | |
76dd2c4f DM |
57 | known_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 |
65 | void |
66 | known_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 |
74 | void |
75 | known_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 | 91 | const known_function * |
6bd31b33 | 92 | known_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 | ||
111 | const known_function * | |
112 | known_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 | ||
121 | const known_function * | |
122 | known_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 | ||
133 | const known_function * | |
134 | known_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 */ |