From d88c8df70342fcd6817e23f243ff38d0fe42fc6b Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 25 Aug 2020 09:26:05 -0400 Subject: [PATCH] analyzer: fix ICE on initializers for unsized array fields [PR96777] gcc/analyzer/ChangeLog: PR analyzer/96777 * region-model.h (class compound_svalue): Document that all keys must be concrete. (compound_svalue::compound_svalue): Move definition to svalue.cc. * store.cc (binding_map::apply_ctor_to_region): Handle initializers for trailing arrays with incomplete size. * svalue.cc (compound_svalue::compound_svalue): Move definition here from region-model.h. Add assertion that all keys are concrete. gcc/testsuite/ChangeLog: PR analyzer/96777 * gcc.dg/analyzer/pr96777.c: New test. --- gcc/analyzer/region-model.h | 9 ++++----- gcc/analyzer/store.cc | 25 +++++++++++++++++++++++++ gcc/analyzer/svalue.cc | 14 ++++++++++++++ gcc/testsuite/gcc.dg/analyzer/pr96777.c | 12 ++++++++++++ 4 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr96777.c diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h index 79d739e..f325a8b 100644 --- a/gcc/analyzer/region-model.h +++ b/gcc/analyzer/region-model.h @@ -1109,6 +1109,9 @@ namespace ana { mapping, but are required to use an svalue, such as when handling compound assignments and compound return values. + All keys within the underlying binding_map are required to be concrete, + not symbolic. + Instances of this class shouldn't be bound as-is into the store; instead they should be unpacked. Similarly, they should not be nested. */ @@ -1150,11 +1153,7 @@ public: const binding_map *m_map_ptr; }; - compound_svalue (tree type, const binding_map &map) - : svalue (calc_complexity (map), type), - m_map (map) - { - } + compound_svalue (tree type, const binding_map &map); enum svalue_kind get_kind () const FINAL OVERRIDE { return SK_COMPOUND; } const compound_svalue *dyn_cast_compound_svalue () const { return this; } diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc index 298088f..8439366 100644 --- a/gcc/analyzer/store.cc +++ b/gcc/analyzer/store.cc @@ -429,6 +429,31 @@ binding_map::apply_ctor_to_region (const region *parent_reg, tree ctor, const binding_key *k = binding_key::make (mgr->get_store_manager (), child_reg, BK_direct); + /* Handle the case where we have an unknown size for child_reg + (e.g. due to it being a trailing field with incomplete array + type. */ + if (!k->concrete_p ()) + { + /* Assume that sval has a well-defined size for this case. */ + tree sval_type = sval->get_type (); + gcc_assert (sval_type); + HOST_WIDE_INT sval_byte_size = int_size_in_bytes (sval_type); + gcc_assert (sval_byte_size != -1); + bit_size_t sval_bit_size = sval_byte_size * BITS_PER_UNIT; + /* Get offset of child relative to base region. */ + region_offset child_base_offset = child_reg->get_offset (); + gcc_assert (!child_base_offset.symbolic_p ()); + /* Convert to an offset relative to the parent region. */ + region_offset parent_base_offset = parent_reg->get_offset (); + gcc_assert (!parent_base_offset.symbolic_p ()); + bit_offset_t child_parent_offset + = (child_base_offset.get_bit_offset () + - parent_base_offset.get_bit_offset ()); + /* Create a concrete key for the child within the parent. */ + k = mgr->get_store_manager ()->get_concrete_binding + (child_parent_offset, sval_bit_size, BK_direct); + } + gcc_assert (k->concrete_p ()); put (k, sval); } } diff --git a/gcc/analyzer/svalue.cc b/gcc/analyzer/svalue.cc index eabb13a..99b5507 100644 --- a/gcc/analyzer/svalue.cc +++ b/gcc/analyzer/svalue.cc @@ -910,6 +910,20 @@ unmergeable_svalue::implicitly_live_p (const svalue_set &live_svalues, /* class compound_svalue : public svalue. */ +compound_svalue::compound_svalue (tree type, const binding_map &map) +: svalue (calc_complexity (map), type), m_map (map) +{ + /* All keys within the underlying binding_map are required to be concrete, + not symbolic. */ +#if CHECKING_P + for (iterator_t iter = begin (); iter != end (); ++iter) + { + const binding_key *key = (*iter).first; + gcc_assert (key->concrete_p ()); + } +#endif +} + /* Implementation of svalue::dump_to_pp vfunc for compound_svalue. */ void diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96777.c b/gcc/testsuite/gcc.dg/analyzer/pr96777.c new file mode 100644 index 0000000..2bb2a4e --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr96777.c @@ -0,0 +1,12 @@ +struct ge { + char au; + char pz[]; +}; + +struct ge tr = { 'X', 'X', }; + +int +main (void) +{ + return tr.pz[0] == 'X'; +} -- 2.7.4