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

Reply via email to