On Thu, 19 Jul 2018, Martin Sebor wrote:

> Here's one more update with tweaks addressing a couple more
> of Bernd's comments:
> 
> 1) correct the use of TREE_STRING_LENGTH() where a number of
> array elements is expected and not bytes
> 2) set CHARTYPE as soon as it's first determined rather than
> trying to extract it again later

Please look at Bernds followup comments.  One additional note:

I see you are ultimatively using CHARTYPE to get at the size
of the access.  That is wrong.

   if (TREE_CODE (arg) == ADDR_EXPR)
     {
+      tree argtype = TREE_TYPE (arg);
+      chartype = argtype;
+
       arg = TREE_OPERAND (arg, 0);
       tree ref = arg;
       if (TREE_CODE (arg) == ARRAY_REF)
        {

so the "access" is of size array_ref_element_size (arg) here.  You
may not simply use TYPE_SIZE_UNIT of sth.

That is, lookign at current trunk,

  if (TREE_CODE (arg) == ADDR_EXPR)
    {
      arg = TREE_OPERAND (arg, 0);
      tree ref = arg;
      if (TREE_CODE (arg) == ARRAY_REF)
        {
          tree idx = TREE_OPERAND (arg, 1);
          if (TREE_CODE (idx) != INTEGER_CST)
            {
              /* Extract the variable index to prevent
                 get_addr_base_and_unit_offset() from failing due to
                 it.  Use it later to compute the non-constant offset
                 into the string and return it to the caller.  */
              varidx = idx;
              ref = TREE_OPERAND (arg, 0);

you should scale the index here by array_ref_element_size (arg).
Or simply rewrite this to instead of using get_addr_base_and_unit_offset,
use get_inner_reference which does all that magic for you.

That is, you shouldn't need chartype.

Richard.


> On 07/19/2018 01:49 PM, Martin Sebor wrote:
> > On 07/19/2018 01:17 AM, Richard Biener wrote:
> > > On Wed, 18 Jul 2018, Martin Sebor wrote:
> > > 
> > > > > > > +      while (TREE_CODE (chartype) != INTEGER_TYPE)
> > > > > > > +    chartype = TREE_TYPE (chartype);
> > > > > > This is a bit concerning.  First under what conditions is chartype
> > > > > > not
> > > > > > going to be an INTEGER_TYPE?  And under what conditions will
> > > > > > extracting
> > > > > > its type ultimately lead to something that is an INTEGER_TYPE?
> > > > > 
> > > > > chartype is usually (maybe even always) pointer type here:
> > > > > 
> > > > >   const char a[] = "123";
> > > > >   extern int i;
> > > > >   n = strlen (&a[i]);
> > > > 
> > > > But your hunch was correct that the loop isn't safe because
> > > > the element type need not be an integer (I didn't know/forgot
> > > > that the function is called for non-strings too).  The loop
> > > > should be replaced by:
> > > > 
> > > >       while (TREE_CODE (chartype) == ARRAY_TYPE
> > > >          || TREE_CODE (chartype) == POINTER_TYPE)
> > > >     chartype = TREE_TYPE (chartype);
> > > 
> > > As this function may be called "late" you need to cope with
> > > the middle-end ignoring type changes and thus happily
> > > passing int *** directly rather than (char *) of that.
> > > 
> > > Also doesn't the above yield int for int *[]?
> > 
> > I don't think it ever gets this far for either a pointer to
> > an array of int, or for an array of pointers to int.  So for
> > something like the following the function fails earlier:
> > 
> >   const int* const a[2] = { ... };
> >   const char* (const *p)[2] = &a;
> > 
> >   int f (void)
> >   {
> >     return __builtin_memcmp (*p, "12345678", 8);
> >   }
> > 
> > (Assuming this is what you were asking about.)
> > 
> > > I guess you really want
> > > 
> > >    if (POINTER_TYPE_P (chartype))
> > >      chartype = TREE_TYPE (chartype);
> > >    while (TREE_CODE (chartype) == ARRAY_TYPE)
> > >      chartype = TREE_TYPE (chartype);
> > > 
> > > ?
> > 
> > That seems to work too.  Attached is an update with this tweak.
> > The update also addresses some of Bernd's comments: it removes
> > the pointless second test in:
> > 
> >     if (TREE_CODE (type) == ARRAY_TYPE
> >         && TREE_CODE (type) != INTEGER_TYPE)
> > 
> > the unused assignment to chartype in:
> > 
> >    else if (DECL_P (arg))
> >      {
> >        array = arg;
> >        chartype = TREE_TYPE (arg);
> >      }
> > 
> > and calls string_constant() instead of strnlen() to compute
> > the length of a generic string.
> > 
> > Other improvements  are possible in this area but they are
> > orthogonal to the bug I'm trying to fix so I'll post separate
> > patches for some of those.
> > 
> > Martin
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)

Reply via email to