analyzer: fix ICEs in region_model::get_lvalue_1 [PR 93388]
authorDavid Malcolm <dmalcolm@redhat.com>
Fri, 14 Feb 2020 02:17:11 +0000 (21:17 -0500)
committerDavid Malcolm <dmalcolm@redhat.com>
Mon, 17 Feb 2020 07:20:36 +0000 (02:20 -0500)
commitf76a88ebf089871dcce215aa0cb1956ccc060895
tree4f8cb05de7bf355d548dc7ce2e8504730058c6bf
parent0993ad65cc4e462223e9337d9b2d3b82a887c6c8
analyzer: fix ICEs in region_model::get_lvalue_1 [PR 93388]

There have been various ICEs with -fanalyzer involving unhandled tree
codes in region_model::get_lvalue_1; PR analyzer/93388 reports various
others e.g. for IMAGPART_EXPR, REALPART_EXPR, and VIEW_CONVERT_EXPR seen
when running the testsuite with -fanalyzer forcibly enabled.

Whilst we could implement lvalue-handling in the region model for every
tree code, for some of these we're straying far from my primary goal for
GCC 10 of implementing a double-free checker for C.

This patch implements a fallback for unimplemented tree codes: create a
dummy region, but mark the new state as being invalid, and stop
exploring state along this path.  It also implements VIEW_CONVERT_EXPR.

Doing so fixes the ICEs, whilst effectively turning off the analyzer
along code paths that use such tree codes.  Hopefully this compromise
is sensible for GCC 10.

gcc/analyzer/ChangeLog:
PR analyzer/93388
* engine.cc (impl_region_model_context::on_unknown_tree_code):
New.
(exploded_graph::get_or_create_node): Reject invalid states.
* exploded-graph.h
(impl_region_model_context::on_unknown_tree_code): New decl.
(point_and_state::point_and_state): Assert that the state is
valid.
* program-state.cc (program_state::program_state): Initialize
m_valid to true.
(program_state::operator=): Copy m_valid.
(program_state::program_state): Likewise for move constructor.
(program_state::print): Print m_valid.
(program_state::dump_to_pp): Likewise.
* program-state.h (program_state::m_valid): New field.
* region-model.cc (region_model::get_lvalue_1): Implement the
default case by returning a new symbolic region and calling
the context's on_unknown_tree_code, rather than issuing an
internal_error.  Implement VIEW_CONVERT_EXPR.
* region-model.h (region_model_context::on_unknown_tree_code): New
vfunc.
(test_region_model_context::on_unknown_tree_code): New.

gcc/testsuite/ChangeLog:
PR analyzer/93388
* gcc.dg/analyzer/torture/20060625-1.c: New test.
* gcc.dg/analyzer/torture/pr51628-30.c: New test.
* gcc.dg/analyzer/torture/pr59037.c: New test.
gcc/analyzer/ChangeLog
gcc/analyzer/engine.cc
gcc/analyzer/exploded-graph.h
gcc/analyzer/program-state.cc
gcc/analyzer/program-state.h
gcc/analyzer/region-model.cc
gcc/analyzer/region-model.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/analyzer/torture/20060625-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/analyzer/torture/pr51628-30.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/analyzer/torture/pr59037.c [new file with mode: 0644]