https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79257
--- Comment #4 from Martin Sebor <msebor at gcc dot gnu.org> ---
One thing I noticed that suggests another possible (and, IMO, the ideal for
this specific case) solution: the warning goes away and GCC emits far better
code when the controlling expression of the loop is (i != 2) as opposed to (i <
2). Contrast the optimal code emitted for foo() below to that for bar():
$ cat c.c && gcc -O2 -c -Wall -fdump-tree-optimized=/dev/stdout
-fsanitize=undefined c.c
void a (void);
char buffer[2];
void foo (void)
{
for (int i = 0; i != 2; i++)
{
if (i == 0)
a ();
__builtin_sprintf (buffer, "%d", i);
}
}
void bar (void)
{
for (int i = 0; i < 2; i++)
{
if (i == 0)
a ();
__builtin_sprintf (buffer, "%d", i);
}
}
;; Function foo (foo, funcdef_no=0, decl_uid=2120, cgraph_uid=0,
symbol_order=1)
foo ()
{
<bb 2> [28.07%]:
a ();
__builtin_sprintf (&buffer, "%d", 0);
__builtin_sprintf (&buffer, "%d", 1); [tail call]
return;
}
c.c: In function ‘bar’:
c.c:21:35: warning: ‘%d’ directive writing between 1 and 10 bytes into a region
of size 2 [-Wformat-overflow=]
__builtin_sprintf (buffer, "%d", i);
^~
c.c:21:34: note: directive argument in the range [0, 2147483646]
__builtin_sprintf (buffer, "%d", i);
^~~~
c.c:21:7: note: ‘__builtin_sprintf’ output between 2 and 11 bytes into a
destination of size 2
__builtin_sprintf (buffer, "%d", i);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;; Function bar (bar, funcdef_no=1, decl_uid=2127, cgraph_uid=1,
symbol_order=2)
Removing basic block 8
bar ()
{
unsigned long ivtmp.7;
int i;
unsigned int _1;
int _8;
unsigned int _10;
<bb 2> [15.00%]:
goto <bb 4>; [100.00%]
<bb 3> [70.00%]:
ivtmp.7_7 = ivtmp.7_3 + 1;
<bb 4> [85.00%]:
# ivtmp.7_3 = PHI <ivtmp.7_7(3), 0(2)>
i_13 = (int) ivtmp.7_3;
if (i_13 == 0)
goto <bb 5>; [33.00%]
else
goto <bb 6>; [67.00%]
<bb 5> [28.05%]:
a ();
__builtin_sprintf (&buffer, "%d", 0);
goto <bb 3>; [100.00%]
<bb 6> [56.95%]:
__builtin_sprintf (&buffer, "%d", i_13);
_1 = (unsigned int) ivtmp.7_3;
_10 = _1 + 1;
_8 = (int) _10;
if (_8 <= 1)
goto <bb 3>; [73.66%]
else
goto <bb 7>; [26.34%]
<bb 7> [15.00%]:
return;
}