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.