diff options
author | David Malcolm <dmalcolm@redhat.com> | 2022-12-06 18:24:16 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2022-12-06 18:24:16 -0500 |
commit | dfe2ef7f2b6cac7017f32a0a04f74e1b6d9f1311 (patch) | |
tree | ad0f486c15d0251b91323d06be965402bd95d680 /gcc/analyzer/region-model.cc | |
parent | 2a23b93f944fa78d4284eb5687051c224e5ab08f (diff) | |
download | gcc-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.cc | 8 |
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); |