https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98447
--- Comment #4 from Vincent Lefèvre <vincent-gcc at vinc17 dot net> --- So this can be simplified to 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; } } 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). This could be part of a more general bug: I also get the -Wanalyzer-shift-count-overflow warning if I replace "n = r % 64" by "n = r". While with the initial code, one is certain that the shift is valid, now this depends on the value of r. But since the compiler doesn't know the condition under which this function will be called, it should not assume that r may have any value.