On Wed, Jan 15, 2020 at 06:56:48PM -0500, David Malcolm wrote: > gcc/analyzer/ChangeLog: > PR analyzer/93281 > * region-model.cc > (region_model::convert_byte_offset_to_array_index): Convert > offset_cst to ssizetype before dividing by byte_size. > --- > gcc/analyzer/region-model.cc | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc > index 5c39be4fd7f..b62ddf82a40 100644 > --- a/gcc/analyzer/region-model.cc > +++ b/gcc/analyzer/region-model.cc > @@ -6414,9 +6414,12 @@ region_model::convert_byte_offset_to_array_index (tree > ptr_type, > /* This might not be a constant. */ > tree byte_size = size_in_bytes (elem_type); > > + /* Ensure we're in a signed representation before doing the division. > */ > + tree signed_offset_cst = fold_convert (ssizetype, offset_cst); > + > tree index > = fold_build2 (TRUNC_DIV_EXPR, integer_type_node, > - offset_cst, byte_size); > + signed_offset_cst, byte_size);
I'd say you want to fold_convert byte_size to ssizetype too. Another thing is the integer_type_node, that looks wrong when you are dividing ssizetype by ssizetype. The fold-const.c folders are sensitive to using incorrect types and type mismatches. And, I think fold_build2 is wasteful, you only care if you can simplify it to a constant (just constant or INTEGER_CST only?). So, either use fold_binary (TRUNC_DIV_EXPR, ssizetype, offset_cst, fold_convert (ssizetype, byte_size)) or, if you have checked that both arguments are INTEGER_CSTs, perhaps int_const_binop or so. > if (CONSTANT_CLASS_P (index)) And this would need to be if (index && TREE_CODE (index) == INTEGER_CST) (or if you can handle other constants (index && CONSTANT_CLASS_P (index)). > return get_or_create_constant_svalue (index); Jakub