On 2/17/21 1:47 PM, Jakub Jelinek wrote:
On Wed, Feb 17, 2021 at 01:27:55PM -0700, Martin Sebor wrote:

Not in this patch, but I've looked at what maxobjsize is and wonder why
the roundtrip tree -> HOST_WIDE_INT -> offset_int:
   const offset_int maxobjsize = tree_to_shwi (max_object_size ());
Can't it be
   const offset_int maxobjsize = wi::to_offset (max_object_size ());
?

Yes, that's what it is elsewhere so this should do the same.  I've
changed it.


I'm pretty sure that's because wide_int doesn't have division and
I assumed offset_int didn't either when I originally wrote the code.
I've changed it to use division.

wide_int does have division, otherwise offset_int wouldn't have it either.
One needs to choose if one wants signed or unsigned division, operator /
does signed, one can use wi::{,s,u}div_{trunc,ceil,round} etc.
As maxobjsize shouldn't have MSB set, it probably doesn't matter if one
uses signed or unsigned division.
+         tree nelts = array_type_nelts (reftype);
+         if (integer_all_onesp (nelts))
+           /* Zero length array.  */
+           arrbounds[1] = 0;

Ok then.

+         else
            {
-             tree bnds[] = { TYPE_MIN_VALUE (dom), TYPE_MAX_VALUE (dom) };
-             if (TREE_CODE (arg) == COMPONENT_REF)
-               {
-                 offset_int size = maxobjsize;
-                 if (tree fldsize = component_ref_size (arg))
-                   size = wi::to_offset (fldsize);
-                 arrbounds[1] = wi::lrshift (size, eltsizelog2);
-               }
-             else if (array_at_struct_end_p (arg) || !bnds[0] || !bnds[1])
-               arrbounds[1] = wi::lrshift (maxobjsize, eltsizelog2);
+             tree esz = TYPE_SIZE_UNIT (TREE_TYPE (reftype));
+             if (TREE_CODE (esz) == INTEGER_CST)
+               /* Array element is either not a VLA or it's a VLA with
+                  zero size (such as int A[n][n][0];).  */
+               eltsize = wi::to_offset (esz);
              else
-               arrbounds[1] = (wi::to_offset (bnds[1]) - wi::to_offset 
(bnds[0])
-                               + 1) * eltsize;
+               return false;
+
+             if (TREE_CODE (nelts) == INTEGER_CST)
+               arrbounds[1] = (wi::to_offset (nelts) + 1) * eltsize;
+             else if (eltsize == 0)
+               arrbounds[1] = 0;

Doesn't arrbounds[1] == 0 mean there will be warnings for any accesses?
For eltsize == 0 I think you shouldn't warn when nelts isn't known,
instead of always warning, arr[100000000] will have the same address as
arr[0] ...

This branch is entered for VLAs of zero-length arrays where we want
to warn, like this:

void f (void*);

void g (int n)
{
  int a[n][0];
  ((int*)a)[0] = 0;
  f (a);
}

Martin


Otherwise LGTM.

        Jakub


Reply via email to