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

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
      Known to fail|                            |10.1.0, 11.0
             Blocks|                            |88443
            Summary|False positive              |[10/11 Regression] False
                   |-Wstringop-overflow warning |positive
                   |with -O2                    |-Wstringop-overflow warning
                   |                            |with -O2

--- Comment #7 from Martin Sebor <msebor at gcc dot gnu.org> ---
Thanks for the small test case!  The warning for reference is:

pr94335-c6.C: In function ‘int main()’:
pr94335-c6.C:8:20: warning: writing 1 byte into a region of size 0
[-Wstringop-overflow=]
    8 |     outputs.back() = 1;
      |     ~~~~~~~~~~~~~~~^~~
In file included from
/build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/c++allocator.h:33,
                 from
/build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/allocator.h:46,
                 from
/build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/vector:64,
                 from pr94335-c6.C:3:
/build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/ext/new_allocator.h:115:41:
note: at offset 0 to an object with size 0 allocated by ‘operator new’ here
  115 |  return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
      |                           ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~

The warning in this case is actually due to a different problem, this one in
the warning infrastructure itself.  The relevant IL the warning works with
(-fdump-tree-strlen) is below:

main ()
{
  ...
  unsigned char * _48;
  ...
  unsigned char * _59;
  ...
  <bb 2> [local count: 1073741825]:
  ...
  _59 = operator new (2);

  <bb 3> [local count: 1073007519]:
  outputs.D.19139._M_impl.D.18482._M_start = _59;
  _48 = _59 + 2;
  ...
  MEM[(value_type &)_48 + 18446744073709551615] = 1;   <<< warning here
(18446744073709551615 == -2)
  ...
}

To determine the size of what _48 points to the warning code calls the
compute_objsize() function.  It returns zero because of a design limitation: it
returns the size of the remaining space in the object (i.e., the full size of
the pointed-to object minus the offset, which is 2 in this case).  The caller
has no way to increase the size it gets back by its negative offset (the large
number which is -2).

I have a rewritten the function to avoid this (and other problems with it) and
expect to have a fix for GCC 11, and possibly even for GCC 10.2.

Since this is a different problem than the originally reported bug I don't want
to use it to track it.  Feel free to open a separate bug for it.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88443
[Bug 88443] [meta-bug] bogus/missing -Wstringop-overflow warnings

Reply via email to