Message ID | 20210105002258.3038219-1-dmalcolm@redhat.com |
---|---|
State | New |
Headers | show |
Series | [committed] analyzer: fix ICE with -fsanitize=undefined [PR98293] | expand |
On Mon, Jan 04, 2021 at 07:22:58PM -0500, David Malcolm via Gcc-patches wrote: > --- a/gcc/analyzer/store.cc > +++ b/gcc/analyzer/store.cc > @@ -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); > + } The TYPE_FIELDS chain doesn't contain only FIELD_DECLs, can contain other decls (FUNCTION_DECLs, USING_DECLs, TYPE_DECLs, ...). So this should be really skipping chain elts other than FIELD_DECLs. E.g. C++ FE has next_initializable_field function for that, unfortunately the middle-end doesn't. Jakub
diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc index 35a7e2985cd..b4a4d5f3bb2 100644 --- a/gcc/analyzer/store.cc +++ b/gcc/analyzer/store.cc @@ -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); diff --git a/gcc/testsuite/gcc.dg/analyzer/pr98293.c b/gcc/testsuite/gcc.dg/analyzer/pr98293.c new file mode 100644 index 00000000000..f750c902440 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr98293.c @@ -0,0 +1,2 @@ +/* { dg-additional-options "-fsanitize=undefined" } */ +#include "../pr93399.c"