analyzer: fix ICE with -fsanitize=undefined [PR98293]

-fsanitize=undefined with calls to nonnull functions
creates struct __ubsan_nonnull_arg_data instances
with CONSTRUCTORs for RECORD_TYPEs with NULL index values.
The analyzer was mistakenly using INTEGER_CST for these
fields, leading to ICEs.

Fix the issue by iterating through the fields in the type
for such cases, imitating similar logic in varasm.c's
output_constructor.

gcc/analyzer/ChangeLog:
	PR analyzer/98293
	* store.cc (binding_map::apply_ctor_to_region): When "index" is
	NULL, iterate through the fields for RECORD_TYPEs, rather than
	creating an INTEGER_CST index.

gcc/testsuite/ChangeLog:
	PR analyzer/98293
	* gcc.dg/analyzer/pr98293.c: New test.
This commit is contained in:
David Malcolm 2021-01-04 19:20:32 -05:00
parent 7e73f51157
commit 15af33a880
2 changed files with 20 additions and 1 deletions

View File

@ -524,10 +524,27 @@ binding_map::apply_ctor_to_region (const region *parent_reg, tree ctor,
unsigned ix;
tree index;
tree val;
tree parent_type = parent_reg->get_type ();
tree field;
if (TREE_CODE (parent_type) == RECORD_TYPE)
field = TYPE_FIELDS (parent_type);
else
field = NULL_TREE;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), ix, index, val)
{
if (!index)
index = build_int_cst (integer_type_node, ix);
{
/* If index is NULL, then iterate through the fields for
a RECORD_TYPE, or use an INTEGER_CST otherwise.
Compare with similar logic in output_constructor. */
if (field)
{
index = field;
field = DECL_CHAIN (field);
}
else
index = build_int_cst (integer_type_node, ix);
}
else if (TREE_CODE (index) == RANGE_EXPR)
{
tree min_index = TREE_OPERAND (index, 0);

View File

@ -0,0 +1,2 @@
/* { dg-additional-options "-fsanitize=undefined" } */
#include "../pr93399.c"