diff options
author | David Malcolm <dmalcolm@redhat.com> | 2019-12-19 15:50:29 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2020-01-14 18:55:00 -0500 |
commit | 4804c5fe965eef2f346de53d9e896ea2cd88f0b9 (patch) | |
tree | 76c4abc5bfcbe0daa782d729afabba990b77dc42 /gcc/analyzer/sm-signal.cc | |
parent | a6b5f19c37001d7c9974248ffcb65aadba33283c (diff) | |
download | gcc-4804c5fe965eef2f346de53d9e896ea2cd88f0b9.zip gcc-4804c5fe965eef2f346de53d9e896ea2cd88f0b9.tar.gz gcc-4804c5fe965eef2f346de53d9e896ea2cd88f0b9.tar.bz2 |
analyzer: introduce a set of known async-signal-unsafe functions
This patch uses the class function_set from the previous patch to
generalize the test for an fprintf inside a signal handler to
check for a set of known async-signal-unsafe functions.
gcc/analyzer/ChangeLog:
* analyzer-selftests.cc (selftest::run_analyzer_selftests): Call
selftest::analyzer_sm_signal_cc_tests.
* analyzer-selftests.h (selftest::analyzer_sm_signal_cc_tests):
New decl.
* sm-signal.cc: Include "analyzer/function-set.h" and
"analyzer/analyzer-selftests.h".
(get_async_signal_unsafe_fns): New function.
(signal_unsafe_p): Reimplement in terms of the above.
(selftest::analyzer_sm_signal_cc_tests): New function.
gcc/testsuite/ChangeLog:
* gcc.dg/analyzer/signal-5.c: New test.
Diffstat (limited to 'gcc/analyzer/sm-signal.cc')
-rw-r--r-- | gcc/analyzer/sm-signal.cc | 57 |
1 files changed, 50 insertions, 7 deletions
diff --git a/gcc/analyzer/sm-signal.cc b/gcc/analyzer/sm-signal.cc index ee41d19..0057ab9 100644 --- a/gcc/analyzer/sm-signal.cc +++ b/gcc/analyzer/sm-signal.cc @@ -56,6 +56,8 @@ along with GCC; see the file COPYING3. If not see #include "analyzer/diagnostic-manager.h" #include "shortest-paths.h" #include "analyzer/exploded-graph.h" +#include "analyzer/function-set.h" +#include "analyzer/analyzer-selftests.h" #if ENABLE_ANALYZER @@ -246,16 +248,40 @@ public: tree m_fndecl; }; -/* Return true if CALL is known to be unsafe to call from a signal handler. */ +/* Get a set of functions that are known to be unsafe to call from an + async signal handler. */ -static bool -signal_unsafe_p (tree callee_fndecl) +static function_set +get_async_signal_unsafe_fns () { - // TODO: maintain a list of known unsafe functions - if (is_named_call_p (callee_fndecl, "fprintf")) - return true; + // TODO: populate this list more fully + static const char * const async_signal_unsafe_fns[] = { + /* This array must be kept sorted. */ + "fprintf", + "free", + "malloc", + "printf", + "snprintf", + "sprintf", + "vfprintf", + "vprintf", + "vsnprintf", + "vsprintf" + }; + const size_t count + = sizeof(async_signal_unsafe_fns) / sizeof (async_signal_unsafe_fns[0]); + function_set fs (async_signal_unsafe_fns, count); + return fs; +}; - return false; +/* Return true if FNDECL is known to be unsafe to call from a signal + handler. */ + +static bool +signal_unsafe_p (tree fndecl) +{ + function_set fs = get_async_signal_unsafe_fns (); + return fs.contains_decl_p (fndecl); } /* Implementation of state_machine::on_stmt vfunc for signal_state_machine. */ @@ -325,4 +351,21 @@ make_signal_state_machine (logger *logger) return new signal_state_machine (logger); } +#if CHECKING_P + +namespace selftest { + +/* Run all of the selftests within this file. */ + +void +analyzer_sm_signal_cc_tests () +{ + function_set fs = get_async_signal_unsafe_fns (); + fs.assert_sorted (); + fs.assert_sane (); +} + +} // namespace selftest + +#endif /* CHECKING_P */ #endif /* #if ENABLE_ANALYZER */ |