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.