diff options
author | David Malcolm <dmalcolm@redhat.com> | 2020-01-23 12:19:20 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2020-01-27 10:10:48 -0500 |
commit | 342e14ffa30e9163a1a75e0a4fb21b6883d58dbe (patch) | |
tree | 5db63fd77e1d2cf9af6ed4898839f0fe0df9dcc5 /gcc/analyzer/region-model.h | |
parent | 317346b271638d405970fbcc3d043a1f8dc098cb (diff) | |
download | gcc-342e14ffa30e9163a1a75e0a4fb21b6883d58dbe.zip gcc-342e14ffa30e9163a1a75e0a4fb21b6883d58dbe.tar.gz gcc-342e14ffa30e9163a1a75e0a4fb21b6883d58dbe.tar.bz2 |
analyzer: fix setjmp-detection and support sigsetjmp
This patch removes the hack in is_setjmp_call_p of looking for
"setjmp" and "_setjmp", replacing it with some logic adapted from
special_function_p in calls.c, ignoring up to 2 leading underscores from
the fndecl's name when checking for a function by name.
It also requires that such functions are "extern" and at file scope
for them to be matched.
The patch also generalizes the setjmp/longjmp handling in the analyzer
to also work with sigsetjmp/siglongjmp. Doing so requires generalizing
some hardcoded functions in diagnostics (which were hardcoded to avoid
user-facing messages referring to "_setjmp", which is an implementation
detail) - the patch adds a new function, get_user_facing_name for this,
for use on calls that matched is_named_call_p and
is_specical_named_call_p.
gcc/analyzer/ChangeLog:
* analyzer.cc (is_named_call_p): Check that fndecl is "extern"
and at file scope. Potentially disregard prefix _ or __ in
fndecl's name. Bail if the identifier is NULL.
(is_setjmp_call_p): Expect a gcall rather than plain gimple.
Remove special-case check for leading prefix, and also check for
sigsetjmp.
(is_longjmp_call_p): Also check for siglongjmp.
(get_user_facing_name): New function.
* analyzer.h (is_setjmp_call_p): Expect a gcall rather than plain
gimple.
(get_user_facing_name): New decl.
* checker-path.cc (setjmp_event::get_desc): Use
get_user_facing_name to avoid hardcoding the function name.
(rewind_event::rewind_event): Add rewind_info param, using it to
initialize new m_rewind_info field, and strengthen the assertion.
(rewind_from_longjmp_event::get_desc): Use get_user_facing_name to
avoid hardcoding the function name.
(rewind_to_setjmp_event::get_desc): Likewise.
* checker-path.h (setjmp_event::setjmp_event): Add setjmp_call
param and use it to initialize...
(setjmp_event::m_setjmp_call): New field.
(rewind_event::rewind_event): Add rewind_info param.
(rewind_event::m_rewind_info): New protected field.
(rewind_from_longjmp_event::rewind_from_longjmp_event): Add
rewind_info param.
(class rewind_to_setjmp_event): Move rewind_info field to parent
class.
* diagnostic-manager.cc (diagnostic_manager::add_events_for_eedge):
Update setjmp-handling for is_setjmp_call_p requiring a gcall;
pass the call to the new setjmp_event.
* engine.cc (exploded_node::on_stmt): Update for is_setjmp_call_p
requiring a gcall.
(stale_jmp_buf::emit): Use get_user_facing_name to avoid
hardcoding the function names.
(exploded_node::on_longjmp): Pass the longjmp_call when
constructing rewind_info.
(rewind_info_t::add_events_to_path): Pass the rewind_info_t to the
rewind_from_longjmp_event's ctor.
* exploded-graph.h (rewind_info_t::rewind_info_t): Add
longjmp_call param.
(rewind_info_t::get_longjmp_call): New.
(rewind_info_t::m_longjmp_call): New.
* region-model.cc (region_model::on_setjmp): Update comment to
indicate this is also for sigsetjmp.
* region-model.h (struct setjmp_record): Likewise.
(class setjmp_svalue): Likewise.
gcc/testsuite/ChangeLog:
* gcc.dg/analyzer/sigsetjmp-5.c: New test.
* gcc.dg/analyzer/sigsetjmp-6.c: New test.
Diffstat (limited to 'gcc/analyzer/region-model.h')
-rw-r--r-- | gcc/analyzer/region-model.h | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h index f7fb7b0..70e3eb4 100644 --- a/gcc/analyzer/region-model.h +++ b/gcc/analyzer/region-model.h @@ -718,8 +718,8 @@ is_a_helper <poisoned_svalue *>::test (svalue *sval) namespace ana { -/* A bundle of information recording a setjmp call, corresponding roughly - to a jmp_buf. */ +/* A bundle of information recording a setjmp/sigsetjmp call, corresponding + roughly to a jmp_buf. */ struct setjmp_record { @@ -739,8 +739,9 @@ struct setjmp_record const gcall *m_setjmp_call; }; -/* Concrete subclass of svalue representing setjmp buffers, so that - longjmp can potentially "return" to an entirely different function. */ +/* Concrete subclass of svalue representing buffers for setjmp/sigsetjmp, + so that longjmp/siglongjmp can potentially "return" to an entirely + different function. */ class setjmp_svalue : public svalue { |