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

--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Adjusted testcase that fails also with -m64:
struct A { unsigned char a[84]; };
struct B { unsigned char b[216]; };
struct C { union { struct A c; struct B d; }; };
struct D { unsigned char e[65536]; unsigned int f; __SIZE_TYPE__ g; };

void
foo (struct D *s)
{
  struct C t;
  unsigned char *e = s->e + 64;
  unsigned int l = s->f;
  __SIZE_TYPE__ o = s->g;
  if (o > 512)
    o -= 512;
  o -= 204;
  if (o > sizeof t.c.a || o + l > sizeof t.c.a)
    l = 0;
  else
    __builtin_memcpy (e, t.c.a + o, l);
}

If this warning would be done during vrp2 when there are still asserts
available rather than in a separate pass right after it, or if it used evrp
analyzer, guess it could easily find out from the guarding condition that the
range is narrower.
But even if it doesn't, I think we shouldn't warn even for:
void
bar (struct D *s)
{
  struct C t;
  unsigned char *e = s->e + 64;
  unsigned int l = s->f;
  __SIZE_TYPE__ o = s->g;
  if (o > 512)
    o -= 512;
  o -= 204;
  __builtin_memcpy (e, t.c.a + o, l);
}

  # RANGE ~[18446744073709550900, 18446744073709551411]
  o_10 = o_3 + 18446744073709551412;
  # RANGE [0, 4294967295] NONZERO 4294967295
  _1 = (long unsigned int) l_7;
  _2 = &t.D.1913.c.a + o_10;
  __builtin_memcpy (e_5, _2, _1);

we should treat at least anti-ranges where both min and max are completely
outside of the bounds of the object as effectively VARYING, it doesn't tell us
any interesting information.

Reply via email to