https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104746

--- Comment #5 from Martin Sebor <msebor at gcc dot gnu.org> ---
(In reply to Martin Liška from comment #3)

This is an example of the "symbolic constraints involving multiple arguments"
that I mentioned in comment #1.  There is no logic to determine from the
complex relationship between the lengths of the two strings that their sum also
constrains the output of the call to avoid the overflow.  A similar example of
the same problem is below.  The conditional guarantees that each of i and j
produces exactly one digit on output, but the all the warning logic considers
is the range of the arguments, which is [0, INT_MAX].  Unlike in the string
case, I think here Ranger could actually set the range of i and j to be [0, 9]
on the assumption the sum doesn't overflow, but that would still not avoid the
warning unless the code also checked the range of the sum.

$ cat b.c && gcc -O2 -S -Wall -Wformat-overflow=2 b.c

char a[3];

void f (int i, int j)
{
  if (i < 0 || j < 0 || i + j > 9)
    return;

  __builtin_sprintf (a, "%u%u", i, j);
}
b.c: In function ‘f’:
b.c:8:26: warning: ‘%u’ directive writing between 1 and 10 bytes into a region
of size 4 [-Wformat-overflow=]
    8 |   __builtin_sprintf (a, "%u%u", i, j);
      |                          ^~
b.c:8:25: note: using the range [0, 4294967295] for directive argument
    8 |   __builtin_sprintf (a, "%u%u", i, j);
      |                         ^~~~~~
b.c:8:25: note: using the range [0, 4294967295] for directive argument
b.c:8:3: note: ‘__builtin_sprintf’ output between 3 and 21 bytes into a
destination of size 4
    8 |   __builtin_sprintf (a, "%u%u", i, j);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Reply via email to