aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/known-function-manager.cc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2022-09-09 17:11:42 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2022-09-09 17:11:42 -0400
commit07e30160beaa207f56f170900fac0d799c6af410 (patch)
tree76a87f37f5031b99f173e7f152f8bfd172e10515 /gcc/analyzer/known-function-manager.cc
parent084dc9a0c6cec14596093ad077fc3e25c6b99bc3 (diff)
downloadgcc-07e30160beaa207f56f170900fac0d799c6af410.zip
gcc-07e30160beaa207f56f170900fac0d799c6af410.tar.gz
gcc-07e30160beaa207f56f170900fac0d799c6af410.tar.bz2
analyzer: add support for plugin-supplied known function behaviors
This patch adds the ability for plugins to register "known functions" with the analyzer, identified by name. If -fanalyzer sees a call to such a function (with no body), it will use a plugin-provided subclass of the new known_function abstract base class to model the possible outcomes of the function call. gcc/ChangeLog: * Makefile.in (ANALYZER_OBJS): Add analyzer/known-function-manager.o. gcc/analyzer/ChangeLog: * analyzer.h (class known_function_manager): New forward decl. (class known_function): New. (plugin_analyzer_init_iface::register_known_function): New. * engine.cc: Include "analyzer/known-function-manager.h". (plugin_analyzer_init_impl::plugin_analyzer_init_impl): Add known_fn_mgr param. (plugin_analyzer_init_impl::register_state_machine): Add LOC_SCOPE. (plugin_analyzer_init_impl::register_known_function): New. (plugin_analyzer_init_impl::m_known_fn_mgr): New. (impl_run_checkers): Update plugin callback invocation to use eng's known_function_manager. * known-function-manager.cc: New file. * known-function-manager.h: New file. * region-model-manager.cc (region_model_manager::region_model_manager): Pass logger to m_known_fn_mgr's ctor. * region-model.cc (region_model::update_for_zero_return): New. (region_model::update_for_nonzero_return): New. (maybe_simplify_upper_bound): New. (region_model::maybe_get_copy_bounds): New. (region_model::get_known_function): New. (region_model::on_call_pre): Handle plugin-supplied known functions. * region-model.h: Include "analyzer/known-function-manager.h". (region_model_manager::get_known_function_manager): New. (region_model_manager::m_known_fn_mgr): New. (call_details::get_model): New accessor. (region_model::maybe_get_copy_bounds): New decl. (region_model::update_for_zero_return): New decl. (region_model::update_for_nonzero_return): New decl. (region_model::get_known_function): New decl. (region_model::get_known_function_manager): New. gcc/testsuite/ChangeLog: * gcc.dg/plugin/analyzer_known_fns_plugin.c: New test plugin. * gcc.dg/plugin/known-fns-1.c: New test. * gcc.dg/plugin/plugin.exp (plugin_test_list): Add the new plugin and test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/analyzer/known-function-manager.cc')
-rw-r--r--gcc/analyzer/known-function-manager.cc78
1 files changed, 78 insertions, 0 deletions
diff --git a/gcc/analyzer/known-function-manager.cc b/gcc/analyzer/known-function-manager.cc
new file mode 100644
index 0000000..f0fd4fc
--- /dev/null
+++ b/gcc/analyzer/known-function-manager.cc
@@ -0,0 +1,78 @@
+/* Support for plugin-supplied behaviors of known functions.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "function.h"
+#include "analyzer/analyzer.h"
+#include "diagnostic-core.h"
+#include "analyzer/analyzer-logging.h"
+#include "stringpool.h"
+#include "analyzer/known-function-manager.h"
+
+#if ENABLE_ANALYZER
+
+namespace ana {
+
+/* class known_function_manager : public log_user. */
+
+known_function_manager::known_function_manager (logger *logger)
+: log_user (logger)
+{
+}
+
+known_function_manager::~known_function_manager ()
+{
+ /* Delete all owned kfs. */
+ for (auto iter : m_map_id_to_kf)
+ delete iter.second;
+}
+
+void
+known_function_manager::add (const char *name, known_function *kf)
+{
+ LOG_FUNC_1 (get_logger (), "registering %s", name);
+ tree id = get_identifier (name);
+ m_map_id_to_kf.put (id, kf);
+}
+
+const known_function *
+known_function_manager::get_by_identifier (tree identifier)
+{
+ known_function **slot = m_map_id_to_kf.get (identifier);
+ if (slot)
+ return *slot;
+ else
+ return NULL;
+}
+
+const known_function *
+known_function_manager::get_by_fndecl (tree fndecl)
+{
+ if (tree identifier = DECL_NAME (fndecl))
+ return get_by_identifier (identifier);
+ return NULL;
+}
+
+} // namespace ana
+
+#endif /* #if ENABLE_ANALYZER */