https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61773

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #3)
> Proper testcase (string init was missing):
> 
> char *stpcpy (char*, const char *);
> char *foo (void)
> {
>   char *p = __builtin_calloc (64, 1);
>   char *q = __builtin_calloc (64, 1);
>   __builtin_strcat (q, "abcde");
>   __builtin_strcat (p, "ab");
>   p[1] = 'a';
>   __builtin_strcat (p, q);
>   return q;
> }
> 
> this isn't optimized either, only when p[0] = 'a'; is there the last
> strcat will be optimized with known strlen of p.  Hmm, a p[1] = '\0'
> isn't optimized either.
> 
> Unfortunately strlen isn't very verbose in its -details dump.

Ok, those are all because the store is

  MEM[ptr, 1] = ...

while only a zero offset MEM is handled in handle_char_store.  For
non-constant offset this gets handled by handle_pointer_plus.

It seems to me that all builtin handling will have a similar issue
when faced with arguments of &MEM[ptr_1, <nonzero-offset>] (zero-offset
should be folded to plain ptr_1 of course, so doesn't happen).

Simple

char *stpcpy (char*, const char *);
char *foo (void)
{
  char *p = __builtin_calloc (64, 1);
  char *q = __builtin_calloc (64, 1);
  __builtin_strcat (q, "abcde");
  __builtin_strcat (p, "ab");
  p = p + 1;
  __builtin_strcat (p, q);
  return q;
}

isn't optimized because we get

  _10 = p_3 + _9;
  __builtin_memcpy (_10, "ab", 3);
  p_12 = p_3 + 1;
  __builtin_strcat (p_12, q_5);

and likely p_3 string-info is invalidated instead of made a copy of that
of _10 (as _9 is zero).

char *stpcpy (char*, const char *);
char *foo (char *q)
{
  char *p = __builtin_strdup ("abcde");
  p = p + 1;
  __builtin_strcat (p, "blah");
  return q;
}

is also not handled well as we don't seem to recognize strdup?

Reply via email to