aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/region-model.h
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2020-01-23 12:19:20 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2020-01-27 10:10:48 -0500
commit342e14ffa30e9163a1a75e0a4fb21b6883d58dbe (patch)
tree5db63fd77e1d2cf9af6ed4898839f0fe0df9dcc5 /gcc/analyzer/region-model.h
parent317346b271638d405970fbcc3d043a1f8dc098cb (diff)
downloadgcc-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.h9
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
{