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

            Bug ID: 88251
           Summary: -Wformat-truncation=2 false alarms when compiling
                    gzip, Emacs
           Product: gcc
           Version: 8.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

-Wformat-truncation can falsely report a buffer overflow in code that is trying
to be careful and catch overflows before they happen. Although this bug report
seems related to Bug#83431, strlen is not involved so it seems to be simpler or
lower-level than Bug#83431.

I ran into this problem when trying to compile an experimental version of
Emacs, and Jim Meyering ran into a similar problem when trying to build GNU
gzip <https://debbugs.gnu.org/32025>.

I observed the problem in GCC 8.2.1 20181105 (Red Hat 8.2.1-5).

To reproduce the problem, use the command:

gcc -O2 -S -Wformat-truncation=2 strerror_r.i

to compile this program:

typedef unsigned long size_t;
extern int snprintf (char *__restrict, size_t,
                     const char *__restrict __format, ...)
  __attribute__ ((__nothrow__))
  __attribute__ ((__format__ (__printf__, 3, 4)));
int
rpl_strerror_r (int errnum, char *buf, size_t buflen)
{
  if (buflen <= 1)
    return 34;
  return snprintf (buf, buflen, "Unknown error %d", errnum);
}

GCC incorrectly reports a diagnostic, as follows.

strerror_r.i: In function ‘rpl_strerror_r’:
strerror_r.i:11:36: warning: ‘Unknown error ’ directive output truncated
writing 14 bytes into a region of size 2 [-Wformat-truncation=]
   return snprintf (buf, buflen, "Unknown error %d", errnum);
                                  ~~^~~~~~~~~~~~
strerror_r.i:11:10: note: ‘snprintf’ output between 16 and 26 bytes into a
destination of size 2
   return snprintf (buf, buflen, "Unknown error %d", errnum);
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Somehow GCC gets confused into thinking that buflen == 2 in the last printf
call. However, the correct assumption is that buflen >= 2.

Reply via email to