Commit 5aebfb71 by David Malcolm

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 342e14ff,
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 ().
parent 5c8a1211
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.
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment