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

Reply via email to