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 guess you really want

   if (POINTER_TYPE_P (chartype))
     chartype = TREE_TYPE (chartype);
   while (TREE_CODE (chartype) == ARRAY_TYPE)
     chartype = TREE_TYPE (chartype);

?

>      if (TREE_CODE (chartype) != INTEGER_TYPE)
>       return NULL;
> 
> I will update the patch before committing.
> 
> FWIW, it seems like it would be useful to extend the function to
> non-string arguments.  That way it would be able to return array
> initializers in cases like this:
> 
>   const struct A { int a[2]; }
>     a = { { 1, 2 } },
>     b = { { 1, 2 } };
> 
>   int f (void)
>   {
>     return __builtin_memcmp (&a, &b, sizeof a);
>   }
> 
> which would in turn make it possible to fold the result of
> such calls analogously to strlen or strcmp.
> 
> Martin
> 
> 

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

Reply via email to