[committed] analyzer: fix ICE on globals with unknown size [PR93388]
David Malcolm
dmalcolm@redhat.com
Wed Oct 14 20:49:21 GMT 2020
This patch fixes an ICE seen when attempting to build various existing
tests in our testsuite with -fanalyzer, including
gcc.c-torture/compile/980816-1.c.
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to master as 61a43de58cb6de7212a622060500ad0a0fd94fae.
gcc/analyzer/ChangeLog:
PR analyzer/93388
* region-model.cc (region_model::get_initial_value_for_global):
Fall back to returning an initial_svalue if
decl_region::get_svalue_for_initializer fails.
* region.cc (decl_region::get_svalue_for_initializer): Don't
attempt to create a compound_svalue if the region has an unknown
size.
gcc/testsuite/ChangeLog:
PR analyzer/93388
* gcc.dg/analyzer/data-model-21.c: New test.
---
gcc/analyzer/region-model.cc | 37 ++++++++++---------
gcc/analyzer/region.cc | 16 ++++++--
gcc/testsuite/gcc.dg/analyzer/data-model-21.c | 8 ++++
3 files changed, 40 insertions(+), 21 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-21.c
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 922e0361e59..06c0c8668ac 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -1345,26 +1345,27 @@ region_model::get_initial_value_for_global (const region *reg) const
if ((called_from_main_p () && !DECL_EXTERNAL (decl))
|| TREE_READONLY (decl))
{
- /* Get the initializer value for base_reg. */
- const svalue *base_reg_init
- = base_reg->get_svalue_for_initializer (m_mgr);
- gcc_assert (base_reg_init);
- if (reg == base_reg)
- return base_reg_init;
- else
+ /* Attempt to get the initializer value for base_reg. */
+ if (const svalue *base_reg_init
+ = base_reg->get_svalue_for_initializer (m_mgr))
{
- /* Get the value for REG within base_reg_init. */
- binding_cluster c (base_reg);
- c.bind (m_mgr->get_store_manager (), base_reg, base_reg_init,
- BK_direct);
- const svalue *sval
- = c.get_any_binding (m_mgr->get_store_manager (), reg);
- if (sval)
+ if (reg == base_reg)
+ return base_reg_init;
+ else
{
- if (reg->get_type ())
- sval = m_mgr->get_or_create_cast (reg->get_type (),
- sval);
- return sval;
+ /* Get the value for REG within base_reg_init. */
+ binding_cluster c (base_reg);
+ c.bind (m_mgr->get_store_manager (), base_reg, base_reg_init,
+ BK_direct);
+ const svalue *sval
+ = c.get_any_binding (m_mgr->get_store_manager (), reg);
+ if (sval)
+ {
+ if (reg->get_type ())
+ sval = m_mgr->get_or_create_cast (reg->get_type (),
+ sval);
+ return sval;
+ }
}
}
}
diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc
index 0820893a9b4..adf0e2c3ce3 100644
--- a/gcc/analyzer/region.cc
+++ b/gcc/analyzer/region.cc
@@ -927,7 +927,9 @@ decl_region::get_svalue_for_constructor (tree ctor,
Get an svalue for the initial value of this region at entry to
"main" (either based on DECL_INITIAL, or implicit initialization to
- zero. */
+ zero.
+
+ Return NULL if there is a problem. */
const svalue *
decl_region::get_svalue_for_initializer (region_model_manager *mgr) const
@@ -935,12 +937,20 @@ decl_region::get_svalue_for_initializer (region_model_manager *mgr) const
tree init = DECL_INITIAL (m_decl);
if (!init)
{
- /* Implicit initialization to zero; use a compound_svalue for it. */
+ /* Implicit initialization to zero; use a compound_svalue for it.
+ Doing so requires that we have a concrete binding for this region,
+ which can fail if we have a region with unknown size
+ (e.g. "extern const char arr[];"). */
+ const binding_key *binding
+ = binding_key::make (mgr->get_store_manager (), this, BK_direct);
+ if (binding->symbolic_p ())
+ return NULL;
+
binding_cluster c (this);
c.zero_fill_region (mgr->get_store_manager (), this);
return mgr->get_or_create_compound_svalue (TREE_TYPE (m_decl),
c.get_map ());
- }
+ }
if (TREE_CODE (init) == CONSTRUCTOR)
return get_svalue_for_constructor (init, mgr);
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-21.c b/gcc/testsuite/gcc.dg/analyzer/data-model-21.c
new file mode 100644
index 00000000000..b952bcb9748
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-21.c
@@ -0,0 +1,8 @@
+extern const char XtStrings[];
+
+void unknown_fn (void *);
+
+void test (void)
+{
+ unknown_fn ((char*)&XtStrings[429]);
+}
--
2.26.2
More information about the Gcc-patches
mailing list