Compiling the following code with "gcc-11 -fanalyzer -c"
void f (unsigned long *p, int r, int i)
{
int b = 64, n = r % 64;
while (i >= 0 && b >= 0)
{
if (b <= n)
p[i--] = 1UL << b;
b -= n;
}
}
gives:
warn-shiftcount.c: In function ‘f’:
warn-shiftcount.c:8:22: warning: shift by count (‘64’) >= precision of type (‘6’) [-Wanalyzer-shift-count-overflow]
8 | p[i--] = 1UL << b;
| ~~~~^~~~
‘f’: events 1-5
|
| 5 | while (i >= 0 && b >= 0)
| | ~~~~~~~^~~~~~~~~
| | |
| | (1) following ‘true’ branch...
| 6 | {
| 7 | if (b <= n)
| | ~
| | |
| | (2) ...to here
| | (3) following ‘true’ branch (when ‘b <= n’)...
| 8 | p[i--] = 1UL << b;
| | ~~~ ~~~~~~~~
| | | |
| | | (5) shift by count ‘64’ here
| | (4) ...to here
This warning is incorrect, since 1UL << b is in the "if" branch,
where b <= n and n <= 63 (thus b <= 63).
No such issue with gcc-10 and before.
This makes testing of GNU MPFR fail (this testcase was derived from
GNU MPFR's random2.c).