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

            Bug ID: 110333
           Summary: GCC 13 -Wformat-overflow=2 should reflect real libc
                    limits for sprintf
           Product: gcc
           Version: 13.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

This bug report follows up to GCC bug#88993 which was resolved as fixed in
2019. Although bug#88993 was fixed for printf, it remains for sprintf. We have
been disabling -Wformat-overflow=2 in Gnulib-using applications like coreutils
and Emacs because of this false positive. Since bug#88993 is reported as fixed
I tried enabling -Wformat-overflow=2 today, but still see problems with
sprintf.

To reproduce the bug, compile the following with "gcc -S -Wformat-overflow=2
foo.c" using gcc (GCC) 13.1.1 20230511 (Red Hat 13.1.1-2) x86-64:

  int sprintf (char *restrict, const char *restrict, ...)
    __attribute__ ((nothrow));
  typedef unsigned long long ull;
  char *
  human_readable (ull n, char *buf, ull from, ull to)
  {
    long double dto = to;
    long double damt = n * (from / dto);
    sprintf (buf, "%.0Lf", damt);
    return buf;
  }
  static char buffer[10000];
  char *
  call_human_readable (ull n, ull from, ull to)
  {
    return human_readable (n, buffer, from, to);
  }

gcc's output is:

  foo.c: In function ‘human_readable’:
  foo.c:9:20: warning: ‘%.0Lf’ directive output between 1 and 4934 bytes may
exceed minimum required size of 4095 [-Wformat-overflow=]
      9 |     sprintf (buf, "%.0Lf", damt);
        |                    ^~~~~

This is a false positive, as the output buffer is plenty large enough. In fact,
as the code stands the sprintf can generate at most 40 bytes including the
terminating NUL byte.

printf does not generate a similar warning.

The libc limit is INT_MAX bytes, not 4095 bytes. I assume the "4095" is a
revenant of an old glibc bug that is no longer of practical interest. Let's
change it to INT_MAX instead.

Reply via email to