analyzer: fix ICE on globals with unknown size [PR93388]
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. 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.
This commit is contained in:
parent
12b267cc60
commit
61a43de58c
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
8
gcc/testsuite/gcc.dg/analyzer/data-model-21.c
Normal file
8
gcc/testsuite/gcc.dg/analyzer/data-model-21.c
Normal file
@ -0,0 +1,8 @@
|
||||
extern const char XtStrings[];
|
||||
|
||||
void unknown_fn (void *);
|
||||
|
||||
void test (void)
|
||||
{
|
||||
unknown_fn ((char*)&XtStrings[429]);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user