aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2020-01-28 10:06:24 -0800
committerDavid Malcolm <dmalcolm@redhat.com>2020-01-28 15:52:05 -0500
commit5aebfb71763c7c8d0bb96adcd0a5f94de96a2a13 (patch)
tree115311105d9d94f85dcb1a5d20f933c02d045959
parent5c8a1211b9873a1b69ef7b2fddae181535bc3b0a (diff)
downloadgcc-5aebfb71763c7c8d0bb96adcd0a5f94de96a2a13.zip
gcc-5aebfb71763c7c8d0bb96adcd0a5f94de96a2a13.tar.gz
gcc-5aebfb71763c7c8d0bb96adcd0a5f94de96a2a13.tar.bz2
analyzer: fix ICE when longjmp isn't marked 'noreturn' (PR 93316)
Comments 11-16 within PR analyzer/93316 discuss an ICE in some setjmp tests seen on AIX and powerpc-darwin9. The issue turned out to be an implicit assumption that longjmp is marked "noreturn". There are two places in engine.cc where the code attempted to locate the longjmp GIMPLE_CALL by finding the final stmt within its supernode, in one place casting it via "as_a <gcall *>", in the other using it as the location_t of the "rewinding from longjmp..." event. When longjmp isn't marked noreturn, its basic block and hence supernode can have additional stmts after the longjmp; in the setjmp-3.c case this was a GIMPLE_RETURN, leading to a ICE when casting this to a GIMPLE_CALL. This patch fixes the two places in question to use the rewind_info_t::get_longjmp_call member function introduced by 342e14ffa30e9163a1a75e0a4fb21b6883d58dbe, fixing the ICE (and ensuring the correct location_t is used for events). gcc/analyzer/ChangeLog: PR analyzer/93316 * engine.cc (rewind_info_t::update_model): Get the longjmp call stmt via get_longjmp_call () rather than assuming it is the last stmt in the longjmp's supernode. (rewind_info_t::add_events_to_path): Get the location_t for the rewind_from_longjmp_event via get_longjmp_call () rather than from the supernode's get_end_location ().
-rw-r--r--gcc/analyzer/ChangeLog10
-rw-r--r--gcc/analyzer/engine.cc12
2 files changed, 12 insertions, 10 deletions
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index cea973d..c665ac1 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,5 +1,15 @@
2020-01-28 David Malcolm <dmalcolm@redhat.com>
+ PR analyzer/93316
+ * engine.cc (rewind_info_t::update_model): Get the longjmp call
+ stmt via get_longjmp_call () rather than assuming it is the last
+ stmt in the longjmp's supernode.
+ (rewind_info_t::add_events_to_path): Get the location_t for the
+ rewind_from_longjmp_event via get_longjmp_call () rather than from
+ the supernode's get_end_location ().
+
+2020-01-28 David Malcolm <dmalcolm@redhat.com>
+
* region-model.cc (poisoned_value_diagnostic::emit): Update for
renaming of warning_at overload to warning_meta.
* sm-file.cc (file_leak::emit): Likewise.
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 2bc0aff..9acec70 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -1333,21 +1333,13 @@ void
rewind_info_t::update_model (region_model *model,
const exploded_edge &eedge)
{
- const exploded_node &src_enode = *eedge.m_src;
- const program_point &src_point = src_enode.get_point ();
-
- const gimple *last_stmt
- = src_point.get_supernode ()->get_last_stmt ();
- gcc_assert (last_stmt);
- const gcall *longjmp_call = as_a <const gcall *> (last_stmt);
-
const program_point &longjmp_point = eedge.m_src->get_point ();
const program_point &setjmp_point = eedge.m_dest->get_point ();
gcc_assert (longjmp_point.get_stack_depth ()
>= setjmp_point.get_stack_depth ());
- model->on_longjmp (longjmp_call,
+ model->on_longjmp (get_longjmp_call (),
get_setjmp_call (),
setjmp_point.get_stack_depth (), NULL);
}
@@ -1368,7 +1360,7 @@ rewind_info_t::add_events_to_path (checker_path *emission_path,
emission_path->add_event
(new rewind_from_longjmp_event
- (&eedge, src_point.get_supernode ()->get_end_location (),
+ (&eedge, get_longjmp_call ()->location,
src_point.get_fndecl (),
src_stack_depth, this));
emission_path->add_event