aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/region-model.cc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2022-12-06 18:24:16 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2022-12-06 18:24:16 -0500
commitdfe2ef7f2b6cac7017f32a0a04f74e1b6d9f1311 (patch)
treead0f486c15d0251b91323d06be965402bd95d680 /gcc/analyzer/region-model.cc
parent2a23b93f944fa78d4284eb5687051c224e5ab08f (diff)
downloadgcc-dfe2ef7f2b6cac7017f32a0a04f74e1b6d9f1311.zip
gcc-dfe2ef7f2b6cac7017f32a0a04f74e1b6d9f1311.tar.gz
gcc-dfe2ef7f2b6cac7017f32a0a04f74e1b6d9f1311.tar.bz2
analyzer: don't create bindings or binding keys for empty regions [PR107882]
PR analyzer/107882 reports an ICE, due to trying to get a compound svalue for this binding: cluster for: a: key: {bytes 0-3} value: {UNKNOWN()} key: {empty} value: {UNKNOWN()} key: {bytes 4-7} value: {UNKNOWN()} where there's an binding to the unknown value of zero bits in size "somewhere" within "a" (perhaps between bits 3 and 4?) This makes no sense, so this patch adds an assertion that we never attempt to create a binding key for an empty region, and adds early rejection of attempts to get or set the values of such regions, fixing the ICE. gcc/analyzer/ChangeLog: PR analyzer/107882 * region-model.cc (region_model::get_store_value): Return an unknown value for empty regions. (region_model::set_value): Bail on empty regions. * region.cc (region::empty_p): New. * region.h (region::empty_p): New decl. * state-purge.cc (same_binding_p): Bail if either region is empty. * store.cc (binding_key::make): Assert that a concrete binding's bit_size must be > 0. (binding_cluster::mark_region_as_unknown): Bail on empty regions. (binding_cluster::get_binding): Likewise. (binding_cluster::remove_overlapping_bindings): Likewise. (binding_cluster::on_unknown_fncall): Don't conjure values for empty regions. (store::fill_region): Bail on empty regions. * store.h (class concrete_binding): Update comment to reflect that the range of bits must be non-empty. (concrete_binding::concrete_binding): Assert that bit range is non-empty. gcc/testsuite/ChangeLog: PR analyzer/107882 * gcc.dg/analyzer/memcpy-pr107882.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/analyzer/region-model.cc')
-rw-r--r--gcc/analyzer/region-model.cc8
1 files changed, 8 insertions, 0 deletions
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 430c0e9..18eaf22 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -2321,6 +2321,10 @@ const svalue *
region_model::get_store_value (const region *reg,
region_model_context *ctxt) const
{
+ /* Getting the value of an empty region gives an unknown_svalue. */
+ if (reg->empty_p ())
+ return m_mgr->get_or_create_unknown_svalue (reg->get_type ());
+
check_region_for_read (reg, ctxt);
/* Special-case: handle var_decls in the constant pool. */
@@ -3159,6 +3163,10 @@ region_model::set_value (const region *lhs_reg, const svalue *rhs_sval,
gcc_assert (lhs_reg);
gcc_assert (rhs_sval);
+ /* Setting the value of an empty region is a no-op. */
+ if (lhs_reg->empty_p ())
+ return;
+
check_region_size (lhs_reg, rhs_sval, ctxt);
check_region_for_write (lhs_reg, ctxt);