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

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Blocks|                            |83819

--- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> ---
The code gating the strlen multi-character store optimization tries to enable
it only for stores into objects of character types but in r279392, for MEM_REF
arguments, it also considers casts like in the assignment that is dropped here:

  MEM <short unsigned int> [(char * {ref-all})&u16_1] = 0;

This was done to detect out-of-bounds stores to allocated objects such as in

  void *p = malloc (3);
  const char a[] = "123";
  memcpy (p, a, sizeof a);

where the memcpy is transformed into

  MEM <unsigned int> [(char * {ref-all})p_3] = 3355185;

r279392 wasn't supposed to introduce any new optimization, so I think the bug
is actually latent, in the handling of stores of single, non-zero bytes over
previously zeroed out arrays of two or more bytes.  Here's a test case that
operates only on char arrays with no casts that reproduces the underlying
problem:

int main (void)
{
  char a[] = { 1, 2 };
  const char b[] = { 0, 0 };
  const char c[] = { 2 };
  __builtin_memcpy (a, b, 2);
  // The above is transformed into
  //   MEM <short unsigned int> [(char * {ref-all})&a] = 0;
  // which is then dropped because of the non-nul store below.
  __builtin_memcpy (a, c, 1);

  volatile char *p = a;
  if (p[0] != 2 || p[1] != 0)
    __builtin_abort ();
}


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83819
[Bug 83819] [meta-bug] missing strlen optimizations

Reply via email to