analyzer: fix ICE when longjmp isn't marked 'noreturn' (PR 93316)
authorDavid Malcolm <dmalcolm@redhat.com>
Tue, 28 Jan 2020 18:06:24 +0000 (10:06 -0800)
committerDavid Malcolm <dmalcolm@redhat.com>
Tue, 28 Jan 2020 20:52:05 +0000 (15:52 -0500)
commit5aebfb71763c7c8d0bb96adcd0a5f94de96a2a13
tree115311105d9d94f85dcb1a5d20f933c02d045959
parent5c8a1211b9873a1b69ef7b2fddae181535bc3b0a
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 ().
gcc/analyzer/ChangeLog
gcc/analyzer/engine.cc