analyzer: fix ICE with pointers between stack frames (PR 93438)
authorDavid Malcolm <dmalcolm@redhat.com>
Fri, 31 Jan 2020 14:20:38 +0000 (09:20 -0500)
committerDavid Malcolm <dmalcolm@redhat.com>
Fri, 31 Jan 2020 19:26:44 +0000 (14:26 -0500)
commit455f58ec50465aed9d92dc31d68708a05e499388
treeded6d41104c29eb1d934c7ef0e90f6856aeb3860
parent5910b14503dd82772dfeca5336a0176f9b1d260a
analyzer: fix ICE with pointers between stack frames (PR 93438)

PR analyzer/93438 reports an ICE when merging two region_models
in which an older stack frame has a local pointing to a local in
a more recent stack frame.

  stack
    older frame
      int *: "ow" --+
                    |
    newer frame     |
      int: "pk" <---+

The root cause is that the state-merging code assumes that all frame
regions in the merged model have already been created.
stack_region::can_merge_p iterates through the frames, creating
and populating each merged frame in turn, so when it attempts to
populate the older frame, it attempts to reference the newer frame in
the merged model, which doesn't exist yet.

This patch reworks stack_region::can_merge_p to use a two-pass approach
in which all frames in the merged model are created first, and then
are all populated, fixing the bug.

gcc/analyzer/ChangeLog:
PR analyzer/93438
* region-model.cc (stack_region::can_merge_p): Split into a two
pass approach, creating all stack regions first, then populating
them.
(selftest::test_state_merging): Add test coverage for (a) the case
of self-merging a model in which a local in an older stack frame
points to a local in a more recent stack frame (which previously
would ICE), and (b) the case of self-merging a model in which a
local points to a global (which previously worked OK).

gcc/testsuite/ChangeLog:
PR analyzer/93438
* gcc.dg/analyzer/torture/pr93438.c: New test.
* gcc.dg/analyzer/torture/pr93438-2.c: New test.
gcc/analyzer/ChangeLog
gcc/analyzer/region-model.cc
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/analyzer/torture/pr93438-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/analyzer/torture/pr93438.c [new file with mode: 0644]