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.

Reply via email to