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

--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #7)
> 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.

It tells us that the index is always out-of-bounds in case one is above
and one is below the range of valid values.  But yes, the quality
of the diagnostic is lacking.

Note we never reported ranges that overlap the valid indexes and the cited
anti-range above definitely does.

Reply via email to