public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug middle-end/111118] New: Bogus -Wstringop-overread with -std=gnu++20 -O2 and std::vector<bool>
@ 2023-08-23 12:27 rogerio.souza at gmail dot com
  2023-08-23 14:54 ` [Bug middle-end/111118] " pinskia at gcc dot gnu.org
  2023-08-23 15:49 ` redi at gcc dot gnu.org
  0 siblings, 2 replies; 3+ messages in thread
From: rogerio.souza at gmail dot com @ 2023-08-23 12:27 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 111118
           Summary: Bogus -Wstringop-overread with -std=gnu++20 -O2 and
                    std::vector<bool>
           Product: gcc
           Version: 13.2.0
            Status: UNCONFIRMED
          Keywords: alias, diagnostic, missed-optimization, patch
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rogerio.souza at gmail dot com
  Target Milestone: ---

The following C++ code compiled with "-c -O1 -std=gnu++20
-Werror=stringop-overread" emits a bogus warning/error with gcc trunk, while it
works without problem when using "-O1 -std=gnu++17" or "-O0 -std=gnu++20"
instead. Tested on compiler explorer on x64 Linux
"https://godbolt.org/z/491jTvj65":

#include <vector>

struct S {
    std::vector<bool> p;
    void foo();
};

#ifdef INLINE
inline
#endif
void S::foo() {
    p.reserve(64);
}

=======================

The code above works fine when running on GCC 12.3.0, but GCC starts raising
the warning bellow sicne GCC v13.1.

In file included from
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/vector:62,
                 from <source>:1:
In static member function 'static constexpr _Up* std::__copy_move<_IsMove,
true, std::random_access_iterator_tag>::__copy_m(_Tp*, _Tp*, _Up*) [with _Tp =
long unsigned int; _Up = long unsigned int; bool _IsMove = false]',
    inlined from 'constexpr _OI std::__copy_move_a2(_II, _II, _OI) [with bool
_IsMove = false; _II = long unsigned int*; _OI = long unsigned int*]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_algobase.h:506:30,
    inlined from 'constexpr _OI std::__copy_move_a1(_II, _II, _OI) [with bool
_IsMove = false; _II = long unsigned int*; _OI = long unsigned int*]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_algobase.h:533:42,
    inlined from 'constexpr _OI std::__copy_move_a(_II, _II, _OI) [with bool
_IsMove = false; _II = long unsigned int*; _OI = long unsigned int*]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_algobase.h:540:31,
    inlined from 'constexpr _OI std::copy(_II, _II, _OI) [with _II = long
unsigned int*; _OI = long unsigned int*]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_algobase.h:633:7,
    inlined from 'constexpr std::vector<bool, _Alloc>::iterator
std::vector<bool, _Alloc>::_M_copy_aligned(const_iterator, const_iterator,
iterator) [with _Alloc = std::allocator<bool>]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_bvector.h:1303:28,
    inlined from 'constexpr void std::vector<bool,
_Alloc>::_M_reallocate(size_type) [with _Alloc = std::allocator<bool>]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/vector.tcc:851:40,
    inlined from 'constexpr void std::vector<bool, _Alloc>::reserve(size_type)
[with _Alloc = std::allocator<bool>]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_bvector.h:1091:17,
    inlined from 'void S::foo()' at <source>:12:14:
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_algobase.h:437:30:
warning: 'void* __builtin_memmove(void*, const void*, long unsigned int)'
writing between 9 and 9223372036854775807 bytes into a region of size 8
overflows the destination [-Wstringop-overflow=]
  437 |             __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
      |             ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/x86_64-linux-gnu/bits/c++allocator.h:33,
                 from
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/allocator.h:46,
                 from
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/vector:63:
In member function '_Tp* std::__new_allocator<_Tp>::allocate(size_type, const
void*) [with _Tp = long unsigned int]',
    inlined from 'constexpr _Tp* std::allocator< <template-parameter-1-1>
>::allocate(std::size_t) [with _Tp = long unsigned int]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/allocator.h:198:40,
    inlined from 'static constexpr _Tp*
std::allocator_traits<std::allocator<_Up> >::allocate(allocator_type&,
size_type) [with _Tp = long unsigned int]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/alloc_traits.h:482:28,
    inlined from 'constexpr std::_Bvector_base<_Alloc>::_Bit_pointer
std::_Bvector_base<_Alloc>::_M_allocate(std::size_t) [with _Alloc =
std::allocator<bool>]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_bvector.h:643:48,
    inlined from 'constexpr void std::vector<bool,
_Alloc>::_M_reallocate(size_type) [with _Alloc = std::allocator<bool>]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/vector.tcc:849:43,
    inlined from 'constexpr void std::vector<bool, _Alloc>::reserve(size_type)
[with _Alloc = std::allocator<bool>]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_bvector.h:1091:17,
    inlined from 'void S::foo()' at <source>:12:14:
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/new_allocator.h:147:55:
note: destination object of size 8 allocated by 'operator new'
  147 |         return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n *
sizeof(_Tp)));
      |                                                       ^
ASM generation compiler returned: 0
In file included from
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/vector:62,
                 from <source>:1:
In static member function 'static constexpr _Up* std::__copy_move<_IsMove,
true, std::random_access_iterator_tag>::__copy_m(_Tp*, _Tp*, _Up*) [with _Tp =
long unsigned int; _Up = long unsigned int; bool _IsMove = false]',
    inlined from 'constexpr _OI std::__copy_move_a2(_II, _II, _OI) [with bool
_IsMove = false; _II = long unsigned int*; _OI = long unsigned int*]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_algobase.h:506:30,
    inlined from 'constexpr _OI std::__copy_move_a1(_II, _II, _OI) [with bool
_IsMove = false; _II = long unsigned int*; _OI = long unsigned int*]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_algobase.h:533:42,
    inlined from 'constexpr _OI std::__copy_move_a(_II, _II, _OI) [with bool
_IsMove = false; _II = long unsigned int*; _OI = long unsigned int*]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_algobase.h:540:31,
    inlined from 'constexpr _OI std::copy(_II, _II, _OI) [with _II = long
unsigned int*; _OI = long unsigned int*]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_algobase.h:633:7,
    inlined from 'constexpr std::vector<bool, _Alloc>::iterator
std::vector<bool, _Alloc>::_M_copy_aligned(const_iterator, const_iterator,
iterator) [with _Alloc = std::allocator<bool>]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_bvector.h:1303:28,
    inlined from 'constexpr void std::vector<bool,
_Alloc>::_M_reallocate(size_type) [with _Alloc = std::allocator<bool>]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/vector.tcc:851:40,
    inlined from 'constexpr void std::vector<bool, _Alloc>::reserve(size_type)
[with _Alloc = std::allocator<bool>]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_bvector.h:1091:17,
    inlined from 'void S::foo()' at <source>:12:14:
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_algobase.h:437:30:
warning: 'void* __builtin_memmove(void*, const void*, long unsigned int)'
writing between 9 and 9223372036854775807 bytes into a region of size 8
overflows the destination [-Wstringop-overflow=]
  437 |             __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
      |             ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/x86_64-linux-gnu/bits/c++allocator.h:33,
                 from
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/allocator.h:46,
                 from
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/vector:63:
In member function '_Tp* std::__new_allocator<_Tp>::allocate(size_type, const
void*) [with _Tp = long unsigned int]',
    inlined from 'constexpr _Tp* std::allocator< <template-parameter-1-1>
>::allocate(std::size_t) [with _Tp = long unsigned int]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/allocator.h:198:40,
    inlined from 'static constexpr _Tp*
std::allocator_traits<std::allocator<_Up> >::allocate(allocator_type&,
size_type) [with _Tp = long unsigned int]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/alloc_traits.h:482:28,
    inlined from 'constexpr std::_Bvector_base<_Alloc>::_Bit_pointer
std::_Bvector_base<_Alloc>::_M_allocate(std::size_t) [with _Alloc =
std::allocator<bool>]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_bvector.h:643:48,
    inlined from 'constexpr void std::vector<bool,
_Alloc>::_M_reallocate(size_type) [with _Alloc = std::allocator<bool>]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/vector.tcc:849:43,
    inlined from 'constexpr void std::vector<bool, _Alloc>::reserve(size_type)
[with _Alloc = std::allocator<bool>]' at
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_bvector.h:1091:17,
    inlined from 'void S::foo()' at <source>:12:14:
/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/new_allocator.h:147:55:
note: destination object of size 8 allocated by 'operator new'
  147 |         return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n *
sizeof(_Tp)));
      |                        

=================================

This issue now is realted with "std::vector<bool>", but the issue "Bug 98465 -
Bogus -Wstringop-overread with -std=gnu++20 -O2 and std::string::insert" is
very similar, although it is related with "std::string::insert".

Regards,
Rogerio

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

* [Bug middle-end/111118] Bogus -Wstringop-overread with -std=gnu++20 -O2 and std::vector<bool>
  2023-08-23 12:27 [Bug middle-end/111118] New: Bogus -Wstringop-overread with -std=gnu++20 -O2 and std::vector<bool> rogerio.souza at gmail dot com
@ 2023-08-23 14:54 ` pinskia at gcc dot gnu.org
  2023-08-23 15:49 ` redi at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-08-23 14:54 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|patch                       |

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---

  _5 = MEM[(const struct vector
*)this_2(D)].D.36316._M_impl.D.35789._M_start.D.21297._M_p;
  _6 = MEM[(const struct _Bvector_impl *)this_2(D)].D.35789._M_end_of_storage;
  _7 = _6 - _5;
  _8 = _7 * 8;
  _9 = (long unsigned int) _8;
  if (_9 <= 63)
    goto <bb 3>; [33.00%]
  else
    goto <bb 21>; [67.00%]

  <bb 3> [local count: 354334800]:
  _42 = operator new (8);
  SR.127_14 = MEM <_Bit_type * const> [(struct vector *)this_2(D) + 16B];
  SR.128_15 = MEM <const unsigned int> [(struct vector *)this_2(D) + 24B];
  _16 = MEM[(struct vector
*)this_2(D)].D.36316._M_impl.D.35789._M_start.D.21297._M_p;
  _51 = SR.127_14 - _16;
  _148 = (long unsigned int) _51;
  if (_51 > 8)


There is a missing optimization here.

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

* [Bug middle-end/111118] Bogus -Wstringop-overread with -std=gnu++20 -O2 and std::vector<bool>
  2023-08-23 12:27 [Bug middle-end/111118] New: Bogus -Wstringop-overread with -std=gnu++20 -O2 and std::vector<bool> rogerio.souza at gmail dot com
  2023-08-23 14:54 ` [Bug middle-end/111118] " pinskia at gcc dot gnu.org
@ 2023-08-23 15:49 ` redi at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: redi at gcc dot gnu.org @ 2023-08-23 15:49 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
This seems to avoid the warning:

--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -926,9 +926,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     vector<bool, _Alloc>::
     _M_reallocate(size_type __n)
     {
+      const const_iterator __begin = begin(), __end = end();
+      if ((__end - __begin) > __n)
+       __builtin_unreachable();
       _Bit_pointer __q = this->_M_allocate(__n);
       iterator __start(std::__addressof(*__q), 0);
-      iterator __finish(_M_copy_aligned(begin(), end(), __start));
+      iterator __finish(_M_copy_aligned(__begin, __end, __start));
       this->_M_deallocate();
       this->_M_impl._M_start = __start;
       this->_M_impl._M_finish = __finish;

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

end of thread, other threads:[~2023-08-23 15:49 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-23 12:27 [Bug middle-end/111118] New: Bogus -Wstringop-overread with -std=gnu++20 -O2 and std::vector<bool> rogerio.souza at gmail dot com
2023-08-23 14:54 ` [Bug middle-end/111118] " pinskia at gcc dot gnu.org
2023-08-23 15:49 ` redi 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).