On 1/8/21 12:38 PM, Bruce Korb via Gcc wrote:
    $ bash cc.sh
    + wrn+=' -Werror=format-overflow'
    + gcc -DHAVE_CONFIG_H -I. -I.. -I../autoopts
    -Wno-format-contains-nul -Wall -Werror -Wcast-align
    -Wmissing-prototypes -Wpointer-arith -Wshadow -Wstrict-prototypes
    -Wwrite-strings -Wstrict-aliasing=3 -Wextra -Wno-cast-qual
    -Werror=format-overflow -fno-strict-aliasing -g -O2 -MT gd.o -MD -MP
    -MF .deps/gd.Tpo -c -o gd.o gd.c
    $ bash cc.sh/(edited to do pre-processing only, to wit:)/
    + gcc -DHAVE_CONFIG_H -I. -I.. -I../autoopts -E -o gd.i gd.c
    $ gcc --version
    gcc (SUSE Linux) 7.5.0
    Copyright (C) 2017 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There
    is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
    PURPOSE.

buildPreamble() starts on line 10230.

This is the code that must be confusing to GCC. "def_str" points to the second character in the 520 byte buffer. "def_scan" points to a character that we already know we're going to copy into the destination, so the "spn" function doesn't look at it:

     {
         char * end = spn_ag_char_map_chars(def_scan + 1, 31);
         size_t len = end - def_scan;
         if (len >= 256)
             goto fail_return;
         memcpy(def_str, def_scan, len);
         def_str += len;
         *def_str = '\0';
         def_scan = end;
     }

"spn_ag_char_map_chars" skips over characters that are in the 31st character set. (It's generated.) If there are too many characters in that set, this code fragment will go into failure mode.

*IF* this .i file doesn't generate the error, then Thomas' compiler must be yielding something weird in its preprocessing output. It compiles just fine with my 7.5.0 compiler.


In my testing GCC 7 doesn't warn for any of the sprintf callss
in the translation unit, at least in part because it determine
the size of the destination.

GCC 8 also doesn't warn but it does determine the size.  Here's
the output for the relevant directive (from the output of
-fdump-tree-printf-return-value in GCC versions prior to 10, or
-fdump-tree-strlen in GCC 10 and later).  objsize is the size
of the destination, or 520 bytes here (this is in contrast to
the 255 in the originally reported message). The Result numbers
are the minimum and maximum size of the output (between 0 and
255 characters).

Computing maximum subobject size for def_str_146:
getdefs.c:275: sprintf: objsize = 520, fmtstr = "  %s'"
  Directive 1 at offset 0: "  ", length = 2
    Result: 2, 2, 2, 2 (2, 2, 2, 2)
  Directive 2 at offset 2: "%s"
    Result: 0, 255, 255, 255 (2, 257, 257, 257)
  Directive 3 at offset 4: "'", length = 1
    Result: 1, 1, 1, 1 (3, 258, 258, 258)
  Directive 4 at offset 5: "", length = 1

Besides provable overflow, it's worth noting that -Wformat-overflow
also diagnoses a subset of cases where it can't prove that overflow
cannot happen.  One common case is:

  extern char a[8], b[8];
  sprintf (a, "a=%s", b);

warning: ‘%s’ directive writing up to 7 bytes into a region of size 6 [-Wformat-overflow=]

Although b's length isn't known, GCC uses its size to warn about
the possible overflow.  The solution is to either use precision
to constrain the amount of output or in GCC 10 and later to assert
that b's length is less than 7.

So if in the autogen file def_str is ever less than 258 bytes
I'd expect the warning to trigger with a message close to
the original.

Martin

On 1/8/21 11:01 AM, Jeff Law wrote:
On 1/8/21 10:39 AM, Bruce Korb via Gcc wrote:

Also, GCC's code analysis is wrong. "name_bf" contains *NO MORE* than
MAXNAMELEN characters. That is provable.

"def_str" points into a buffer of size ((MAXNAMELEN * 2) + 8) and at
an offset maximum of MAXNAMELEN+1 (also provable), meaning that at a
minimum there are MAXNAMELEN+6 bytes left in the buffer.

That objected-to sprintf can add a maximum of MAXNAMELEN + 4 to where
"def_str" points.

GCC is wrong. It is unable to figure out how far into the buffer
"def_str" can point.
Can you get a .i file, command line and file a report.  It'd be appreciated.

jeff


Reply via email to