On the following program
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;
}
}
gcc-12 emits the following incorrect warning:
$ gcc-12 -fanalyzer -c warn-shiftcount.c
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
|
Here, due to the "n = r % 64", one has n <= 63, so that "1UL << b"
can be executed only when b <= 63, and the shift is necessarily valid
(no overflow).
Note: gcc-11 is affected too, but not gcc-10.