On Thu, 2020-01-16 at 09:14 +0100, Jakub Jelinek wrote:
> 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

Thanks.

Here's an updated version of the patch which fold_converts both
inputs to the division, and uses fold_binary rather than fold_build2.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu;
verified with -m32 and -m64.

OK for master?

gcc/analyzer/ChangeLog:
        PR analyzer/93281
        * region-model.cc
        (region_model::convert_byte_offset_to_array_index): Convert to
        ssizetype before dividing by byte_size.  Use fold_binary rather
        than fold_build2 to avoid needlessly constructing a tree for the
        non-const case.
---
 gcc/analyzer/region-model.cc | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 5c39be4fd7f..f67572e2d45 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -6414,11 +6414,13 @@ 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);
 
+      /* Try to get a constant by dividing, ensuring that we're in a
+        signed representation first.  */
       tree index
-       = fold_build2 (TRUNC_DIV_EXPR, integer_type_node,
-                      offset_cst, byte_size);
-
-      if (CONSTANT_CLASS_P (index))
+       = fold_binary (TRUNC_DIV_EXPR, ssizetype,
+                      fold_convert (ssizetype, offset_cst),
+                      fold_convert (ssizetype, byte_size));
+      if (index && TREE_CODE (index) == INTEGER_CST)
        return get_or_create_constant_svalue (index);
     }
 
-- 
2.21.0

Reply via email to