public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/96188] New: -Wstringop-overflow false positive
@ 2020-07-13 15:51 derek.mauro at gmail dot com
  2020-07-13 16:49 ` [Bug c++/96188] " msebor at gcc dot gnu.org
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: derek.mauro at gmail dot com @ 2020-07-13 15:51 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 96188
           Summary: -Wstringop-overflow false positive
           Product: gcc
           Version: 10.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: derek.mauro at gmail dot com
  Target Milestone: ---

This is strange issue that started appearing in gcc 10.1. It also seems to
require -O3 and -std=gnu++11 (gnu++14 etc appear unaffected).

Godbolt demo: https://godbolt.org/z/W8MWbz

Test case copy/pasted below.

Use -Werror -Wstringop-overflow -std=gnu++11 -O3

#include <string>
#include <vector>

bool b;

void F() {
  static bool b2 = b;
  for (const int fx : {0}) {
    struct Expectation {
      std::string out;
    };

    std::vector<Expectation> expect = {
        {std::string()},
        {std::string()},
        {std::string()},
    };
    if (b2) {
      expect.push_back({std::string()});
    }

  }
}

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c++/96188] -Wstringop-overflow false positive
  2020-07-13 15:51 [Bug c++/96188] New: -Wstringop-overflow false positive derek.mauro at gmail dot com
@ 2020-07-13 16:49 ` msebor at gcc dot gnu.org
  2020-07-13 17:10 ` [Bug c++/96188] -Wstringop-overflow false positive on std::vector::push_back with -O3 msebor at gcc dot gnu.org
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: msebor at gcc dot gnu.org @ 2020-07-13 16:49 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |diagnostic,
                   |                            |missed-optimization
   Last reconfirmed|                            |2020-07-13
                 CC|                            |msebor at gcc dot gnu.org
             Blocks|                            |88443
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
In bug reports please include the information requested here:
https://gcc.gnu.org/bugs/#need (specifically the compiler outptut).  Links to
external sites are not a substitute since the need not reproduce the same
problem in the future.

This form of the warning first started paying attention to dynamically
allocated memory in GCC 10.  On master, the output is as follows:

pr96188.C: In function ‘void F()’:
pr96188.C:9:18: warning: unused variable ‘fx’ [-Wunused-variable]
    9 |   for (const int fx : {0}) {
      |                  ^~
cc1plus: warning: writing 16 bytes into a region of size 0
[-Wstringop-overflow=]
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/string:41,
                 from pr96188.C:2:
/build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/ext/new_allocator.h:115:41:
note: at offset 112 to an object with size 0 allocated by ‘operator new’ here
  115 |  return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
      |                           ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~

The -Wstringop-overflow warning is based on the MEM store in the abbreviated IL
below (seen in the output of the -fdump-tree-strlen option):

  <bb 6> [local count: 268435456]:
  _87 = operator new (96);      ;; P

  <bb 15>
  __cur_167 = _87 + 32;         ;; P + 32

  <bb 23>
  __cur_172 = __cur_167 + 32;   ;; P + 64

  <bb 33>
  __cur_97 = __cur_172 + 32;    ;; P + 96

  <bb 52>
  MEM <__int128 unsigned> [(char * {ref-all})__cur_97 + 16B] = _119;   ;; P +
96 + 16 == P + 112

The size of the allocation is 96 (it's missing from the warning due to a known
limitation) but the offset is 112.  The warning is doing what it's designed to
do, but it's possible that bb 52 isn't reachable and GCC can't tell.  There's
one jump to bb 52, from bb 51 based on this condition:

  _84 = _87 + 96;
  if (_84 != __cur_97)
    goto <bb 52>; [82.57%]

so that would seem to confirm the theory.  GCC only does limited pointer value
analysis and has no support for pointer value ranges, which is why I suspect it
can't figure out that the inequality in bb 51 implies that bb 52 isn't
reachable.  There are a number of reports of this warning for code that
manipulates arrays and pointers this way.


Referenced Bugs:

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c++/96188] -Wstringop-overflow false positive on std::vector::push_back with -O3
  2020-07-13 15:51 [Bug c++/96188] New: -Wstringop-overflow false positive derek.mauro at gmail dot com
  2020-07-13 16:49 ` [Bug c++/96188] " msebor at gcc dot gnu.org
@ 2020-07-13 17:10 ` msebor at gcc dot gnu.org
  2021-01-21 22:04 ` msebor at gcc dot gnu.org
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: msebor at gcc dot gnu.org @ 2020-07-13 17:10 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=94335
            Summary|-Wstringop-overflow false   |-Wstringop-overflow false
                   |positive                    |positive on
                   |                            |std::vector::push_back with
                   |                            |-O3

--- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> ---
pr94335 talks about some of the issues/challenges with pointers in this
context.  (The problem discussed in pr95353 has a similar test case as this one
but it's due to an already fixed bug in the warning.)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c++/96188] -Wstringop-overflow false positive on std::vector::push_back with -O3
  2020-07-13 15:51 [Bug c++/96188] New: -Wstringop-overflow false positive derek.mauro at gmail dot com
  2020-07-13 16:49 ` [Bug c++/96188] " msebor at gcc dot gnu.org
  2020-07-13 17:10 ` [Bug c++/96188] -Wstringop-overflow false positive on std::vector::push_back with -O3 msebor at gcc dot gnu.org
@ 2021-01-21 22:04 ` msebor at gcc dot gnu.org
  2021-02-17 22:53 ` egor_suvorov at mail dot ru
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: msebor at gcc dot gnu.org @ 2021-01-21 22:04 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|2020-07-13 00:00:00         |2021-1-21
      Known to fail|                            |10.2.0, 11.0

--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> ---
No change in GCC 11 (except for the size in the note):

$ gcc -O3 -S -Wall -std=gnu++11 pr96188.C
pr96188.C: In function ‘void F()’:
pr96188.C:9:18: warning: unused variable ‘fx’ [-Wunused-variable]
    9 |   for (const int fx : {0}) {
      |                  ^~
cc1plus: warning: writing 16 bytes into a region of size 0
[-Wstringop-overflow=]
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/string:41,
                 from pr96188.C:2:
/build/gcc-master/x86_64-pc-linux-gnu/libstdc++-v3/include/ext/new_allocator.h:121:48:
note: at offset 112 into destination object of size 96 allocated by ‘operator
new’
  121 |         return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
      |                                  ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c++/96188] -Wstringop-overflow false positive on std::vector::push_back with -O3
  2020-07-13 15:51 [Bug c++/96188] New: -Wstringop-overflow false positive derek.mauro at gmail dot com
                   ` (2 preceding siblings ...)
  2021-01-21 22:04 ` msebor at gcc dot gnu.org
@ 2021-02-17 22:53 ` egor_suvorov at mail dot ru
  2021-02-17 22:54 ` egor_suvorov at mail dot ru
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: egor_suvorov at mail dot ru @ 2021-02-17 22:53 UTC (permalink / raw)
  To: gcc-bugs

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

Egor Suvorov <egor_suvorov at mail dot ru> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |egor_suvorov at mail dot ru

--- Comment #4 from Egor Suvorov <egor_suvorov at mail dot ru> ---
A possibly related example (also available at Godbolt:
https://godbolt.org/z/P65dx1 )

At my Windows machine the following code

#include <vector>
int main() {
    struct S {  // Defining the structure inside main is important.
        bool x = false;  // Initialization is important.
    };
    std::vector<S> v(3);  // Can also be 2, 3, and 4, but not 0, 1, 5, or 6.
    v.emplace_back(S());
}

yields following when compiled with g++ -O2 -Wextra:

In member function 'void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...)
[with _Args = {main()::S}; _Tp = main()::S; _Alloc =
std::allocator<main()::S>]',
    inlined from 'int main()' at a.cpp:7:19:
cc1plus.exe: warning: writing 1 byte into a region of size 0
[-Wstringop-overflow=]
In file included from
C:/Software/msys64/mingw64/include/c++/10.2.0/x86_64-w64-mingw32/bits/c++allocator.h:33,
                 from
C:/Software/msys64/mingw64/include/c++/10.2.0/bits/allocator.h:46,
                 from C:/Software/msys64/mingw64/include/c++/10.2.0/vector:64,
                 from a.cpp:1:
C:/Software/msys64/mingw64/include/c++/10.2.0/ext/new_allocator.h: In function
'int main()':
C:/Software/msys64/mingw64/include/c++/10.2.0/ext/new_allocator.h:115:41: note:
at offset 3 to an object with size 0 allocated by 'operator new' here
  115 |  return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
      |                           ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~

My g++ version is

g++ (Rev6, Built by MSYS2 project) 10.2.0
Copyright (C) 2020 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.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c++/96188] -Wstringop-overflow false positive on std::vector::push_back with -O3
  2020-07-13 15:51 [Bug c++/96188] New: -Wstringop-overflow false positive derek.mauro at gmail dot com
                   ` (3 preceding siblings ...)
  2021-02-17 22:53 ` egor_suvorov at mail dot ru
@ 2021-02-17 22:54 ` egor_suvorov at mail dot ru
  2021-02-18  0:55 ` [Bug tree-optimization/96188] " msebor at gcc dot gnu.org
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: egor_suvorov at mail dot ru @ 2021-02-17 22:54 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Egor Suvorov <egor_suvorov at mail dot ru> ---
Created attachment 50214
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50214&action=edit
Preprocessor output for Egor Suvorov's example

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug tree-optimization/96188] -Wstringop-overflow false positive on std::vector::push_back with -O3
  2020-07-13 15:51 [Bug c++/96188] New: -Wstringop-overflow false positive derek.mauro at gmail dot com
                   ` (4 preceding siblings ...)
  2021-02-17 22:54 ` egor_suvorov at mail dot ru
@ 2021-02-18  0:55 ` msebor at gcc dot gnu.org
  2021-09-06 11:01 ` pinskia at gcc dot gnu.org
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: msebor at gcc dot gnu.org @ 2021-02-18  0:55 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |alias
          Component|c++                         |tree-optimization

--- Comment #6 from Martin Sebor <msebor at gcc dot gnu.org> ---
The example in comment #4 is due to the same problem/limitation in the
optimizer.  The IL that triggers the warning is below:

  <bb 2> [local count: 1073741833]:
  MEM[(struct _Vector_impl_data *)&v] ={v} {CLOBBER};
  _32 = operator new (3);
  _27 = _32 + 3;                                  <<< _27
  *_32.x = 0;
  MEM[(struct S *)_32 + 1B].x = 0;
  MEM[(struct S *)_32 + 2B].x = 0;
  __cur_3 = &MEM <struct S> [(void *)_32 + 3B];   <<< same as _27
  if (__cur_3 != _27)                             <<< must be false
    goto <bb 3>; [82.57%]
  else
    goto <bb 7>; [17.43%]

  <bb 3> [local count: 797929761]:
  MEM[(struct S *)_32 + 3B] = 0;                  <<< -Wstringop-overflow=
  goto <bb 5>; [100.00%]

GCC doesn't fold the equality (_32 + 3 == &MEM <struct S> [(void *)_32 + 3B]).

A simplified test case for that limitation is below:

$ cat t.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout t.c
struct S { char a[3]; };

void f (struct S *p)
{
  void *q0 = p + 1;
  void *q1 = p->a + sizeof *p;

  if (q0 != q1)   // not folded but should be
    __builtin_abort ();
}

;; Function f (f, funcdef_no=0, decl_uid=1945, cgraph_uid=1, symbol_order=0)

void f (struct S * p)
{
  void * q1;
  void * q0;

  <bb 2> [local count: 1073741824]:
  q0_2 = p_1(D) + 3;
  q1_3 = &MEM <char[3]> [(void *)p_1(D) + 3B];
  if (q0_2 != q1_3)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [100.00%]

  <bb 3> [count: 0]:
  __builtin_abort ();

  <bb 4> [local count: 1073741824]:
  return;

}

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug tree-optimization/96188] -Wstringop-overflow false positive on std::vector::push_back with -O3
  2020-07-13 15:51 [Bug c++/96188] New: -Wstringop-overflow false positive derek.mauro at gmail dot com
                   ` (5 preceding siblings ...)
  2021-02-18  0:55 ` [Bug tree-optimization/96188] " msebor at gcc dot gnu.org
@ 2021-09-06 11:01 ` pinskia at gcc dot gnu.org
  2021-11-23 10:15 ` pinskia at gcc dot gnu.org
  2021-12-02 21:30 ` msebor at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-09-06 11:01 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Martin Sebor from comment #6)
> The example in comment #4 is due to the same problem/limitation in the
> optimizer.  The IL that triggers the warning is below:

I am going to fix this issue as part of PR 102216.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug tree-optimization/96188] -Wstringop-overflow false positive on std::vector::push_back with -O3
  2020-07-13 15:51 [Bug c++/96188] New: -Wstringop-overflow false positive derek.mauro at gmail dot com
                   ` (6 preceding siblings ...)
  2021-09-06 11:01 ` pinskia at gcc dot gnu.org
@ 2021-11-23 10:15 ` pinskia at gcc dot gnu.org
  2021-12-02 21:30 ` msebor at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-11-23 10:15 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |needs-bisection

--- Comment #8 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Derek Mauro from comment #0)
> This is strange issue that started appearing in gcc 10.1. It also seems to
> require -O3 and -std=gnu++11 (gnu++14 etc appear unaffected).

I can't reproduce this with r12-5457-g06be28f64a0b5bfc. So someone should do a
bisect to see when it was fixed.



(In reply to Egor Suvorov from comment #4)
> A possibly related example (also available at Godbolt:
> https://godbolt.org/z/P65dx1 )

This example is fixed with r12-5465-g911b633803dcbb298 (double checked).

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug tree-optimization/96188] -Wstringop-overflow false positive on std::vector::push_back with -O3
  2020-07-13 15:51 [Bug c++/96188] New: -Wstringop-overflow false positive derek.mauro at gmail dot com
                   ` (7 preceding siblings ...)
  2021-11-23 10:15 ` pinskia at gcc dot gnu.org
@ 2021-12-02 21:30 ` msebor at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: msebor at gcc dot gnu.org @ 2021-12-02 21:30 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
      Known to work|                            |12.0

--- Comment #9 from Martin Sebor <msebor at gcc dot gnu.org> ---
Today's trunk doesn't reproduce it but the warning is still issued with GCC 12
for a GCC 11 translation unit, so it must be some library change that's made it
go away.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-12-02 21:30 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-13 15:51 [Bug c++/96188] New: -Wstringop-overflow false positive derek.mauro at gmail dot com
2020-07-13 16:49 ` [Bug c++/96188] " msebor at gcc dot gnu.org
2020-07-13 17:10 ` [Bug c++/96188] -Wstringop-overflow false positive on std::vector::push_back with -O3 msebor at gcc dot gnu.org
2021-01-21 22:04 ` msebor at gcc dot gnu.org
2021-02-17 22:53 ` egor_suvorov at mail dot ru
2021-02-17 22:54 ` egor_suvorov at mail dot ru
2021-02-18  0:55 ` [Bug tree-optimization/96188] " msebor at gcc dot gnu.org
2021-09-06 11:01 ` pinskia at gcc dot gnu.org
2021-11-23 10:15 ` pinskia at gcc dot gnu.org
2021-12-02 21:30 ` msebor at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).