aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/program-state.cc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2020-02-13 21:17:11 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2020-02-17 02:20:36 -0500
commitf76a88ebf089871dcce215aa0cb1956ccc060895 (patch)
tree4f8cb05de7bf355d548dc7ce2e8504730058c6bf /gcc/analyzer/program-state.cc
parent0993ad65cc4e462223e9337d9b2d3b82a887c6c8 (diff)
downloadgcc-f76a88ebf089871dcce215aa0cb1956ccc060895.zip
gcc-f76a88ebf089871dcce215aa0cb1956ccc060895.tar.gz
gcc-f76a88ebf089871dcce215aa0cb1956ccc060895.tar.bz2
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.
Diffstat (limited to 'gcc/analyzer/program-state.cc')
-rw-r--r--gcc/analyzer/program-state.cc21
1 files changed, 19 insertions, 2 deletions
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index 82b921e..fb96e3c 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -573,7 +573,8 @@ sm_state_map::validate (const state_machine &sm,
program_state::program_state (const extrinsic_state &ext_state)
: m_region_model (new region_model ()),
- m_checker_states (ext_state.get_num_checkers ())
+ m_checker_states (ext_state.get_num_checkers ()),
+ m_valid (true)
{
int num_states = ext_state.get_num_checkers ();
for (int i = 0; i < num_states; i++)
@@ -584,7 +585,8 @@ program_state::program_state (const extrinsic_state &ext_state)
program_state::program_state (const program_state &other)
: m_region_model (new region_model (*other.m_region_model)),
- m_checker_states (other.m_checker_states.length ())
+ m_checker_states (other.m_checker_states.length ()),
+ m_valid (true)
{
int i;
sm_state_map *smap;
@@ -610,6 +612,8 @@ program_state::operator= (const program_state &other)
FOR_EACH_VEC_ELT (other.m_checker_states, i, smap)
m_checker_states.quick_push (smap->clone ());
+ m_valid = other.m_valid;
+
return *this;
}
@@ -626,6 +630,8 @@ program_state::program_state (program_state &&other)
FOR_EACH_VEC_ELT (other.m_checker_states, i, smap)
m_checker_states.quick_push (smap);
other.m_checker_states.truncate (0);
+
+ m_valid = other.m_valid;
}
#endif
@@ -693,6 +699,11 @@ program_state::print (const extrinsic_state &ext_state,
pp_newline (pp);
}
}
+ if (!m_valid)
+ {
+ pp_printf (pp, "invalid state");
+ pp_newline (pp);
+ }
}
/* Dump a multiline representation of this state to PP. */
@@ -716,6 +727,12 @@ program_state::dump_to_pp (const extrinsic_state &ext_state,
pp_newline (pp);
}
}
+
+ if (!m_valid)
+ {
+ pp_printf (pp, "invalid state");
+ pp_newline (pp);
+ }
}
/* Dump a multiline representation of this state to OUTF. */