public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-2953] analyzer: fix ICE on RANGE_EXPR in CONSTRUCTORs [PR96763]
@ 2020-08-31 20:08 David Malcolm
0 siblings, 0 replies; only message in thread
From: David Malcolm @ 2020-08-31 20:08 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:0d1b4edc5fff834e8f924b20dd021ded7a21d2d2
commit r11-2953-g0d1b4edc5fff834e8f924b20dd021ded7a21d2d2
Author: David Malcolm <dmalcolm@redhat.com>
Date: Mon Aug 24 09:33:42 2020 -0400
analyzer: fix ICE on RANGE_EXPR in CONSTRUCTORs [PR96763]
gcc/analyzer/ChangeLog:
PR analyzer/96763
* store.cc (binding_map::apply_ctor_to_region): Handle RANGE_EXPR
by calling a new binding_map::apply_ctor_val_to_range subroutine.
Split out the existing non-CONSTRUCTOR-handling code to a new
apply_ctor_pair_to_child_region subroutine.
(binding_map::apply_ctor_val_to_range): New.
(binding_map::apply_ctor_pair_to_child_region): New, split out
from binding_map::apply_ctor_to_region as noted above.
* store.h (binding_map::apply_ctor_val_to_range): New decl.
(binding_map::apply_ctor_pair_to_child_region): New decl.
gcc/testsuite/ChangeLog:
PR analyzer/96763
* g++.dg/analyzer/pr96763.C: New test.
Diff:
---
gcc/analyzer/store.cc | 129 +++++++++++++++++++++++---------
gcc/analyzer/store.h | 8 ++
gcc/testsuite/g++.dg/analyzer/pr96763.C | 13 ++++
3 files changed, 115 insertions(+), 35 deletions(-)
diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc
index 14f7c00bde6..8890a69a6f8 100644
--- a/gcc/analyzer/store.cc
+++ b/gcc/analyzer/store.cc
@@ -419,43 +419,102 @@ binding_map::apply_ctor_to_region (const region *parent_reg, tree ctor,
{
if (!index)
index = build_int_cst (integer_type_node, ix);
- const region *child_reg
- = get_subregion_within_ctor (parent_reg, index, mgr);
- if (TREE_CODE (val) == CONSTRUCTOR)
- apply_ctor_to_region (child_reg, val, mgr);
- else
+ else if (TREE_CODE (index) == RANGE_EXPR)
{
- const svalue *sval = get_svalue_for_ctor_val (val, mgr);
- 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);
+ tree min_index = TREE_OPERAND (index, 0);
+ tree max_index = TREE_OPERAND (index, 1);
+ apply_ctor_val_to_range (parent_reg, mgr, min_index, max_index, val);
+ continue;
+ }
+ apply_ctor_pair_to_child_region (parent_reg, mgr, index, val);
+ }
+}
+
+/* Bind the value VAL into the range of elements within PARENT_REF
+ from MIN_INDEX to MAX_INDEX (including endpoints).
+ For use in handling RANGE_EXPR within a CONSTRUCTOR. */
+
+void
+binding_map::apply_ctor_val_to_range (const region *parent_reg,
+ region_model_manager *mgr,
+ tree min_index, tree max_index,
+ tree val)
+{
+ gcc_assert (TREE_CODE (min_index) == INTEGER_CST);
+ gcc_assert (TREE_CODE (max_index) == INTEGER_CST);
+
+ /* Generate a binding key for the range. */
+ const region *min_element
+ = get_subregion_within_ctor (parent_reg, min_index, mgr);
+ const region *max_element
+ = get_subregion_within_ctor (parent_reg, max_index, mgr);
+ region_offset min_offset = min_element->get_offset ();
+ bit_offset_t start_bit_offset = min_offset.get_bit_offset ();
+ store_manager *smgr = mgr->get_store_manager ();
+ const binding_key *max_element_key
+ = binding_key::make (smgr, max_element, BK_direct);
+ gcc_assert (max_element_key->concrete_p ());
+ const concrete_binding *max_element_ckey
+ = max_element_key->dyn_cast_concrete_binding ();
+ bit_size_t range_size_in_bits
+ = max_element_ckey->get_next_bit_offset () - start_bit_offset;
+ const concrete_binding *range_key
+ = smgr->get_concrete_binding (start_bit_offset, range_size_in_bits,
+ BK_direct);
+ gcc_assert (range_key->concrete_p ());
+
+ /* Get the value. */
+ gcc_assert (TREE_CODE (val) != CONSTRUCTOR);
+ const svalue *sval = get_svalue_for_ctor_val (val, mgr);
+
+ /* Bind the value to the range. */
+ put (range_key, sval);
+}
+
+/* Bind the value VAL into INDEX within PARENT_REF.
+ For use in handling a pair of entries within a CONSTRUCTOR. */
+
+void
+binding_map::apply_ctor_pair_to_child_region (const region *parent_reg,
+ region_model_manager *mgr,
+ tree index, tree val)
+{
+ const region *child_reg
+ = get_subregion_within_ctor (parent_reg, index, mgr);
+ if (TREE_CODE (val) == CONSTRUCTOR)
+ apply_ctor_to_region (child_reg, val, mgr);
+ else
+ {
+ const svalue *sval = get_svalue_for_ctor_val (val, mgr);
+ 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/store.h b/gcc/analyzer/store.h
index 636a9547f2c..0ac93179dc6 100644
--- a/gcc/analyzer/store.h
+++ b/gcc/analyzer/store.h
@@ -344,6 +344,14 @@ public:
region_model_manager *mgr);
private:
+ void apply_ctor_val_to_range (const region *parent_reg,
+ region_model_manager *mgr,
+ tree min_index, tree max_index,
+ tree val);
+ void apply_ctor_pair_to_child_region (const region *parent_reg,
+ region_model_manager *mgr,
+ tree index, tree val);
+
map_t m_map;
};
diff --git a/gcc/testsuite/g++.dg/analyzer/pr96763.C b/gcc/testsuite/g++.dg/analyzer/pr96763.C
new file mode 100644
index 00000000000..1b29e30a8f8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/analyzer/pr96763.C
@@ -0,0 +1,13 @@
+// { dg-do compile { target c++11 } }
+
+struct c0;
+
+struct md {
+ int c0::*jj[2];
+};
+
+void
+n0 ()
+{
+ md{};
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-08-31 20:08 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-31 20:08 [gcc r11-2953] analyzer: fix ICE on RANGE_EXPR in CONSTRUCTORs [PR96763] David Malcolm
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).