https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79257
--- Comment #7 from Vincent Lefèvre <vincent-gcc at vinc17 dot net> --- (In reply to Pierre Chapuis from comment #5) > I think I can reproduce something similar *without* the sanitizer. > > Using GCC 7.1.1, with: > > #include <stdio.h> > int main () { > int i; char obuf[3]; > int start = 0x00; > for (i = start; i <= 0xff; ++i) { > sprintf(obuf, "%02x", i); > } > return 0; > } If 0xff is replaced by 0xfe, the warning disappears. Is the issue due to the fact that i can be 0x100 in the loop (thus with one additional character), but GCC doesn't notice that this value will not be printed? Similarly, I get the warning with for (i = start; i <= 0xfe; i += 2) but not with for (i = start; i <= 0xfd; i += 2) > I get: > > demo.c: In function ‘main’: > demo.c:6:23: warning: ‘sprintf’ may write a terminating nul past the end of > the destination [-Wformat-overflow=] > sprintf(obuf, "%02x", i); > ^~~~~~ > demo.c:6:9: note: ‘sprintf’ output between 3 and 4 bytes into a destination > of size 3 > sprintf(obuf, "%02x", i); > ^~~~~~~~~~~~~~~~~~~~~~~~ IMHO, this seems to be a different bug, otherwise instead of "4 bytes", you would get the number of bytes corresponding to INT_MAX-1 in the message, as in comment 0. > If I set `start` to `0xfb` or `0xfc`, I get the same warning. If I set it to > `0xfe` or `0xff` I don't get a warning. If I set it to `0xfd` I get the > warning *twice*: This might be due to loop unrolling. You can see with -S that the generated asm code has a loop for start = 0xfc, but not for start = 0xfd, 0xfe or 0xff. With start = 0xfd, 3 sprintf are generated, and perhaps there's a warning for 2 of them. Then I wonder why start = 0xfe no longer triggers the warning.