[committed] analyzer: fix ICE on initializers for unsized array fields [PR96777]
David Malcolm
dmalcolm@redhat.com
Wed Aug 26 01:43:44 GMT 2020
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to master as r11-2854-gd88c8df70342fcd6817e23f243ff38d0fe42fc6b.
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 79d739e3a7b..f325a8b8381 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 298088f6ef9..8439366f0b5 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 eabb13affcb..99b5507a43c 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 00000000000..2bb2a4e0be3
--- /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.26.2
More information about the Gcc-patches
mailing list