diff options
author | David Malcolm <dmalcolm@redhat.com> | 2022-08-05 19:45:41 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2022-08-05 19:45:41 -0400 |
commit | e1a9168153d2bf12695844a9ca9f9fc1de8d1ddf (patch) | |
tree | 1ec0493d1273a4b4e8abaf2ee23d13be64ffffc9 /gcc/analyzer/engine.cc | |
parent | cc01a27db5411a4fe354a97b7c86703c5bc81243 (diff) | |
download | gcc-e1a9168153d2bf12695844a9ca9f9fc1de8d1ddf.zip gcc-e1a9168153d2bf12695844a9ca9f9fc1de8d1ddf.tar.gz gcc-e1a9168153d2bf12695844a9ca9f9fc1de8d1ddf.tar.bz2 |
New warning: -Wanalyzer-jump-through-null [PR105947]
This patch adds a new warning to -fanalyzer for jumps through NULL
function pointers.
gcc/analyzer/ChangeLog:
PR analyzer/105947
* analyzer.opt (Wanalyzer-jump-through-null): New option.
* engine.cc (class jump_through_null): New.
(exploded_graph::process_node): Complain about jumps through NULL
function pointers.
gcc/ChangeLog:
PR analyzer/105947
* doc/invoke.texi: Add -Wanalyzer-jump-through-null.
gcc/testsuite/ChangeLog:
PR analyzer/105947
* gcc.dg/analyzer/function-ptr-5.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/analyzer/engine.cc')
-rw-r--r-- | gcc/analyzer/engine.cc | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc index 85b7c5e..e8db00d 100644 --- a/gcc/analyzer/engine.cc +++ b/gcc/analyzer/engine.cc @@ -3705,6 +3705,46 @@ private: bool m_terminate_path; }; +/* A subclass of pending_diagnostic for complaining about jumps through NULL + function pointers. */ + +class jump_through_null : public pending_diagnostic_subclass<jump_through_null> +{ +public: + jump_through_null (const gcall *call) + : m_call (call) + {} + + const char *get_kind () const final override + { + return "jump_through_null"; + } + + bool operator== (const jump_through_null &other) const + { + return m_call == other.m_call; + } + + int get_controlling_option () const final override + { + return OPT_Wanalyzer_jump_through_null; + } + + bool emit (rich_location *rich_loc) final override + { + return warning_at (rich_loc, get_controlling_option (), + "jump through null pointer"); + } + + label_text describe_final_event (const evdesc::final_event &ev) final override + { + return ev.formatted_print ("jump through null pointer here"); + } + +private: + const gcall *m_call; +}; + /* The core of exploded_graph::process_worklist (the main analysis loop), handling one node in the worklist. @@ -4046,6 +4086,15 @@ exploded_graph::process_node (exploded_node *node) logger); if (!call_discovered) { + /* Check for jump through NULL. */ + if (tree fn_ptr = gimple_call_fn (call)) + { + const svalue *fn_ptr_sval + = model->get_rvalue (fn_ptr, &ctxt); + if (fn_ptr_sval->all_zeroes_p ()) + ctxt.warn (new jump_through_null (call)); + } + /* An unknown function or a special function was called at this point, in such case, don't terminate the analysis of the current function. |