On 9/30/19 9:40 PM, Jerry DeLisle wrote:
Copying gcc list for additional thoughts on a possible bogus warning.

On 9/29/19 9:02 AM, Jerry DeLisle wrote:
Hi all,

--- snip ---

diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
index 4ef35561fdd..fc046efbe34 100644
--- a/libgfortran/io/write.c
+++ b/libgfortran/io/write.c
@@ -1031,7 +1031,7 @@ btoa_big (const char *s, char *buffer, int len, GFC_UINTEGER_LARGEST *n)
    else
      {
        const char *p = s + len - 1;
-      for (i = 0; i < len; i++)
+      for (i = 0; i < len - 1; i++)
      {
        char c = *p;


--- snip ---

The first attempt to fix (above) is completely off.  I have tried various combinations of code changes and I am beginning to think the warning is bogus:

In function ‘btoa_big’,
    inlined from ‘write_b’ at ../../../trunk/libgfortran/io/write.c:1217:11: ../../../trunk/libgfortran/io/write.c:1052:6: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  1052 |   *q = '\0';
       |   ~~~^~~~~~

In case it helps, the warning is for the access:

  # .MEM_68 = VDEF <.MEM_71>
  MEM[(char *)_86] = 0;

where _86 is set to

  _86 = &itoa_buf + _43;

and _43 has the range [136, 17179869176].  (The warning needs to
be enhanced a bit to mention the accessed object in this case.)
itoa_buf's DECL_SIZE_UNIT evaluates to 129.

The call to btoa_big in write_b:

      p = btoa_big (source, itoa_buf, len, &n);

is made with len > 16.  If len > sizeof itoa_buf  / 8 then it does
look like btoa_big would write past the end of itoa_buf because it
writes len * 8 bytes into it.  I don't know if the function can be
called with len that large but if not, adding this just above
the call suppresses the warning.

      if (len > sizeof itoa_buf / 8)
        __builtin_unreachable ();

Martin

Using gdb I have watched the pointer address stored in q and the setting of the string of bytes doing the binary to ascii conversion. I have also checked the length of the buffer being used and its is what I would expect with length of 129.

However, the warning only goes away if I add an additional 8 bytes to the buffer (suspicious).

So doing the following eliminates the warning:

diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
index 4ef35561fdd..fd0e46851e4 100644
--- a/libgfortran/io/write.c
+++ b/libgfortran/io/write.c
@@ -1204,7 +1204,7 @@ void
 write_b (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
  {
    const char *p;
-  char itoa_buf[GFC_BTOA_BUF_SIZE];
+  char itoa_buf[GFC_BTOA_BUF_SIZE + 8];
    GFC_UINTEGER_LARGEST n = 0;

    if (len > (int) sizeof (GFC_UINTEGER_LARGEST))

Any suggestions? I am certainly not seeing it.

Regards,

Jerry












Reply via email to