public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/105746] New: vector<union>::resize causes Warray-bounds when optimizer uses __builtin_memcpy or __builtin_memmove
@ 2022-05-27  0:08 albrecht.guendel at web dot de
  2022-07-15  9:12 ` [Bug c++/105746] vector<union>::resize causes Warray-bounds when optimizer uses __builtin_memcpy or __builtin_memmove since r12-2793-g81d6cdd335ffc60c marxin at gcc dot gnu.org
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: albrecht.guendel at web dot de @ 2022-05-27  0:08 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 105746
           Summary: vector<union>::resize causes Warray-bounds when
                    optimizer uses __builtin_memcpy or __builtin_memmove
           Product: gcc
           Version: 10.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: albrecht.guendel at web dot de
  Target Milestone: ---

https://godbolt.org/z/YP5aWjbzM

>From version 10.1 to trunk (both arm-none-eabi, x86-64)
Compiling with: -O3 -Wall -Wextra -Werror

The following code:

#include <vector>

union U //works if is struct
{
    unsigned char data;

    //required to construct from 0xff
    U(const unsigned char raw): data(raw) {} 

    //required by vector::resize
    U(const U& other): data(other.data) {} 
};

auto bug()
{
    std::vector<U> v;
    v.resize(100, 0xff);
    return v;
}

produces the warning:

void* __builtin_memcpy(void*, const void*, long unsigned int)' offset 100 is
out of the bounds [0, 100]

This is the most minimum example i have found.
Noticeable: 
- it only happens when using O3
- it also happens when the compiler decides to use __builtin_memmove instead
(havent found a good minimum example for that; my working-code results in using
memmove)
- replacing the union with a struct/class resolves the issue
- the bug also occurs when resizing with some compile-time known U, instead of
an integer constant (it does not matter which copy-constructor is called by
vector::resize, just that the optimization to __builtin_memcpy is possible).
- clang and other compilers complain about the copy-constructor being
deprecated in this code example. [this one: U(const U& other): data(other.data)
{} ].
And, indeed, replacing it with U(const U& other) = default; actually resolves
the issue. (but maybe the memcpy-optimization is just not triggered?)


I think this is worth investigating because this either hints at some bad
constant propagation or bounds-check. Basically, I dont know, if the warning
triggers erroneously or if the warning has merit due to an optimization bug.
According to other compilers, the code is bad/deprecated.. but gcc does not
warn (and I dont know why other compilers warn here).
In detail, clang says: definition of implicit copy assignment operator for 'U'
is deprecated because it has a user-declared copy constructor
[-Wdeprecated-copy]

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

* [Bug c++/105746] vector<union>::resize causes Warray-bounds when optimizer uses __builtin_memcpy or __builtin_memmove since r12-2793-g81d6cdd335ffc60c
  2022-05-27  0:08 [Bug c++/105746] New: vector<union>::resize causes Warray-bounds when optimizer uses __builtin_memcpy or __builtin_memmove albrecht.guendel at web dot de
@ 2022-07-15  9:12 ` marxin at gcc dot gnu.org
  2022-07-15 15:42 ` [Bug middle-end/105746] " msebor at gcc dot gnu.org
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: marxin at gcc dot gnu.org @ 2022-07-15  9:12 UTC (permalink / raw)
  To: gcc-bugs

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

Martin Liška <marxin at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |marxin at gcc dot gnu.org,
                   |                            |msebor at gcc dot gnu.org
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW
            Summary|vector<union>::resize       |vector<union>::resize
                   |causes Warray-bounds when   |causes Warray-bounds when
                   |optimizer uses              |optimizer uses
                   |__builtin_memcpy or         |__builtin_memcpy or
                   |__builtin_memmove           |__builtin_memmove since
                   |                            |r12-2793-g81d6cdd335ffc60c
   Last reconfirmed|                            |2022-07-15
           Keywords|needs-bisection             |

--- Comment #1 from Martin Liška <marxin at gcc dot gnu.org> ---
Started with r12-2793-g81d6cdd335ffc60c.

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

* [Bug middle-end/105746] vector<union>::resize causes Warray-bounds when optimizer uses __builtin_memcpy or __builtin_memmove since r12-2793-g81d6cdd335ffc60c
  2022-05-27  0:08 [Bug c++/105746] New: vector<union>::resize causes Warray-bounds when optimizer uses __builtin_memcpy or __builtin_memmove albrecht.guendel at web dot de
  2022-07-15  9:12 ` [Bug c++/105746] vector<union>::resize causes Warray-bounds when optimizer uses __builtin_memcpy or __builtin_memmove since r12-2793-g81d6cdd335ffc60c marxin at gcc dot gnu.org
@ 2022-07-15 15:42 ` msebor at gcc dot gnu.org
  2022-11-29 18:24 ` rguenth at gcc dot gnu.org
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: msebor at gcc dot gnu.org @ 2022-07-15 15:42 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|c++                         |middle-end

--- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> ---
The memmove call in the IL the warning is issued for writes past the end of the
allocated block.  My guess is that the call to operator new prevents it from
figuring out that the _M_finish initially zeroed out by the vectorized store to
vectp.132_96 is still clear in bb 5.  This can be confirmed by replacing the
call to operator new with one to __builtin_malloc() which both eliminates the
warning and also results in much more efficient code(*).  There are duplicates
of this problem in Bugzilla.  The root cause is probably the fix for pr101480.

  <bb 2> [local count: 1073741824]:
  vectp.132_96 = &MEM[(struct _Vector_impl_data *)v_2(D)]._M_start;
  MEM <vector(2) long unsigned int> [(union U * *)vectp.132_96] = { 0, 0 };  
<<< zero out _M_finish (and _M_start)
  MEM[(struct _Vector_impl_data *)v_2(D)]._M_end_of_storage = 0B;
  _70 = operator new (100);

  <bb 3> [local count: 1073741824]:
  __builtin_memset (_70, 255, 100);
  _78 = v_2(D)->D.25350._M_impl.D.24657._M_start;    <<< zero
  if (_78 != 0B)
    goto <bb 4>; [89.00%]
  else
    goto <bb 5>; [11.00%]

  <bb 4> [local count: 439275554]:                   <<< unreachable 
  # __cur_127 = PHI <__cur_83(4), _70(3)>
  # __first_120 = PHI <__first_82(4), _78(3)>
  *__cur_127 ={v} {CLOBBER};
  _81 = MEM[(const union U &)__first_120];
  MEM[(union U *)__cur_127] = _81;
  __first_82 = __first_120 + 1;
  __cur_83 = __cur_127 + 1;
  goto <bb 4>; [100.00%]

  <bb 5> [local count: 54292484]:
  __new_finish_85 = _70 + 100;
  _86 = v_2(D)->D.25350._M_impl.D.24657._M_finish;   <<< zero
  if (_86 != 0B)
    goto <bb 6>; [89.00%]
  else
    goto <bb 7>; [11.00%]

  <bb 6> [local count: 48320311]:                    <<< unreachable
  _93 = (sizetype) _86;                              <<< zero
  __builtin_memmove (__new_finish_85, 0B, _93);      <<< warning
  ...


The IL for the function when operator new is replaced with __builtin_malloc:

struct vector bug ()
{
  union U * __new_finish;
  union U * __cur;
  long unsigned int __n;
  union U * _70;

  <bb 2> [local count: 1073741824]:
  _70 = __builtin_malloc (100);
  __builtin_memset (_70, 255, 100);
  __new_finish_84 = _70 + 100;
  v_2(D)->D.25350._M_impl.D.24657._M_start = _70;
  v_2(D)->D.25350._M_impl.D.24657._M_finish = __new_finish_84;
  v_2(D)->D.25350._M_impl.D.24657._M_end_of_storage = __new_finish_84;
  return v_2(D);

}

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

* [Bug middle-end/105746] vector<union>::resize causes Warray-bounds when optimizer uses __builtin_memcpy or __builtin_memmove since r12-2793-g81d6cdd335ffc60c
  2022-05-27  0:08 [Bug c++/105746] New: vector<union>::resize causes Warray-bounds when optimizer uses __builtin_memcpy or __builtin_memmove albrecht.guendel at web dot de
  2022-07-15  9:12 ` [Bug c++/105746] vector<union>::resize causes Warray-bounds when optimizer uses __builtin_memcpy or __builtin_memmove since r12-2793-g81d6cdd335ffc60c marxin at gcc dot gnu.org
  2022-07-15 15:42 ` [Bug middle-end/105746] " msebor at gcc dot gnu.org
@ 2022-11-29 18:24 ` rguenth at gcc dot gnu.org
  2022-11-29 18:48 ` redi at gcc dot gnu.org
  2022-12-27 14:28 ` marxin at gcc dot gnu.org
  4 siblings, 0 replies; 6+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-11-29 18:24 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
      Known to work|                            |13.0
           Keywords|                            |needs-bisection
      Known to fail|13.0                        |

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
Fixed by r13-4393-gcca06f0d6d76b0 on trunk?  Reconfirmed with GCC 12, 11 and 10
but doesn't seem to happen with GCC 9.

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

* [Bug middle-end/105746] vector<union>::resize causes Warray-bounds when optimizer uses __builtin_memcpy or __builtin_memmove since r12-2793-g81d6cdd335ffc60c
  2022-05-27  0:08 [Bug c++/105746] New: vector<union>::resize causes Warray-bounds when optimizer uses __builtin_memcpy or __builtin_memmove albrecht.guendel at web dot de
                   ` (2 preceding siblings ...)
  2022-11-29 18:24 ` rguenth at gcc dot gnu.org
@ 2022-11-29 18:48 ` redi at gcc dot gnu.org
  2022-12-27 14:28 ` marxin at gcc dot gnu.org
  4 siblings, 0 replies; 6+ messages in thread
From: redi at gcc dot gnu.org @ 2022-11-29 18:48 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #3)
> Fixed by r13-4393-gcca06f0d6d76b0 on trunk? 

Yes.

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

* [Bug middle-end/105746] vector<union>::resize causes Warray-bounds when optimizer uses __builtin_memcpy or __builtin_memmove since r12-2793-g81d6cdd335ffc60c
  2022-05-27  0:08 [Bug c++/105746] New: vector<union>::resize causes Warray-bounds when optimizer uses __builtin_memcpy or __builtin_memmove albrecht.guendel at web dot de
                   ` (3 preceding siblings ...)
  2022-11-29 18:48 ` redi at gcc dot gnu.org
@ 2022-12-27 14:28 ` marxin at gcc dot gnu.org
  4 siblings, 0 replies; 6+ messages in thread
From: marxin at gcc dot gnu.org @ 2022-12-27 14:28 UTC (permalink / raw)
  To: gcc-bugs

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

Martin Liška <marxin at gcc dot gnu.org> changed:

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

--- Comment #5 from Martin Liška <marxin at gcc dot gnu.org> ---
Started with r10-5170-g268209f3a0dc07fc.

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

end of thread, other threads:[~2022-12-27 14:28 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-27  0:08 [Bug c++/105746] New: vector<union>::resize causes Warray-bounds when optimizer uses __builtin_memcpy or __builtin_memmove albrecht.guendel at web dot de
2022-07-15  9:12 ` [Bug c++/105746] vector<union>::resize causes Warray-bounds when optimizer uses __builtin_memcpy or __builtin_memmove since r12-2793-g81d6cdd335ffc60c marxin at gcc dot gnu.org
2022-07-15 15:42 ` [Bug middle-end/105746] " msebor at gcc dot gnu.org
2022-11-29 18:24 ` rguenth at gcc dot gnu.org
2022-11-29 18:48 ` redi at gcc dot gnu.org
2022-12-27 14:28 ` marxin 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).