analyzer: handle &STRING_CST in constant pool initializers [PR96642]

In r11-2708-g2867118ddda9b56d991c16022f7d3d634ed08313 I added support to
the analyzer for initialization from var_decls in the global constant
pool.  However, that commit didn't support initialization from
ADDR_EXPR of a STRING_CST leading to an ICE seen in data-model-1.c and
pr94639.c on arm and powerpc64 at least, and as PR analyzer/96642 on
x86_64 at least.

This patch adds support for such initializers, fixing the ICE.

gcc/analyzer/ChangeLog:
	PR analyzer/96642
	* store.cc (get_svalue_for_ctor_val): New.
	(binding_map::apply_ctor_to_region): Call it.

gcc/testsuite/ChangeLog:
	PR analyzer/96642
	* gcc.dg/analyzer/pr96642.c: New test.
This commit is contained in:
David Malcolm 2020-08-15 15:34:21 -04:00
parent 9e02619154
commit 35c5f8fb43
2 changed files with 28 additions and 3 deletions

View File

@ -391,6 +391,22 @@ get_subregion_within_ctor (const region *parent_reg, tree index,
}
}
/* Get the svalue for VAL, a non-CONSTRUCTOR value within a CONSTRUCTOR. */
static const svalue *
get_svalue_for_ctor_val (tree val, region_model_manager *mgr)
{
if (TREE_CODE (val) == ADDR_EXPR)
{
gcc_assert (TREE_CODE (TREE_OPERAND (val, 0)) == STRING_CST);
const string_region *str_reg
= mgr->get_region_for_string (TREE_OPERAND (val, 0));
return mgr->get_ptr_svalue (TREE_TYPE (val), str_reg);
}
gcc_assert (CONSTANT_CLASS_P (val));
return mgr->get_or_create_constant_svalue (val);
}
/* Bind values from CONSTRUCTOR to this map, relative to
PARENT_REG's relationship to its base region. */
@ -415,12 +431,11 @@ binding_map::apply_ctor_to_region (const region *parent_reg, tree ctor,
apply_ctor_to_region (child_reg, val, mgr);
else
{
gcc_assert (CONSTANT_CLASS_P (val));
const svalue *cst_sval = mgr->get_or_create_constant_svalue (val);
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);
put (k, cst_sval);
put (k, sval);
}
}
}

View File

@ -0,0 +1,10 @@
void
ut (void)
{
struct {
char *cc;
} sr[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, "", 0, 0, "",
0, 0, "", 0, 0, "", 0, 0, "", 0, 0, "", 0, 0, 0, 0, 0,
};
}