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;
}

Reply via email to