https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117983
Bug ID: 117983 Summary: [13.2 regression] -Wstringop-overflow false positive for __builtin_memmove from vector::insert Product: gcc Version: 13.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: gasper.azman at gmail dot com Target Milestone: --- Repro on GCC 13.3 and 14: https://godbolt.org/z/EdfGEfGcr code: ``` #include <cstdint> #include <vector> class buffer { void push(std::vector<std::uint8_t> chunk); std::vector<std::uint8_t> _data; }; void buffer::push(std::vector<std::uint8_t> chunk) { if (_data.empty()) { _data.swap(chunk); } else { _data.insert(_data.end(), chunk.begin(), chunk.end()); } } ``` As you can see, perfectly normal. Compiling with `-Wall -Wextra -O3`: x86-64 gcc 14.2 - 661ms (257546B) ~16635 lines filtered In file included from /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/vector:62, from <source>:2: In static member function 'static _Up* std::__copy_move<_IsMove, true, std::random_access_iterator_tag>::__copy_m(_Tp*, _Tp*, _Up*) [with _Tp = unsigned char; _Up = unsigned char; bool _IsMove = false]', inlined from '_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = unsigned char*; _OI = unsigned char*]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_algobase.h:521:30, inlined from '_OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove = false; _II = unsigned char*; _OI = unsigned char*]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_algobase.h:548:42, inlined from '_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = __gnu_cxx::__normal_iterator<unsigned char*, vector<unsigned char> >; _OI = unsigned char*]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_algobase.h:555:31, inlined from '_OI std::copy(_II, _II, _OI) [with _II = __gnu_cxx::__normal_iterator<unsigned char*, vector<unsigned char> >; _OI = unsigned char*]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_algobase.h:651:7, inlined from 'static _ForwardIterator std::__uninitialized_copy<true>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char> >; _ForwardIterator = unsigned char*]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_uninitialized.h:147:27, inlined from '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<unsigned char*, vector<unsigned char> >; _ForwardIterator = unsigned char*]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_uninitialized.h:185:15, inlined from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, allocator<_Tp>&) [with _InputIterator = __gnu_cxx::__normal_iterator<unsigned char*, vector<unsigned char> >; _ForwardIterator = unsigned char*; _Tp = unsigned char]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_uninitialized.h:373:37, inlined from 'void std::vector<_Tp, _Alloc>::_M_range_insert(iterator, _ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = __gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char> >; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/vector.tcc:1022:38, inlined from 'std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(const_iterator, _InputIterator, _InputIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char> >; <template-parameter-2-2> = void; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_vector.h:1488:19, inlined from 'void buffer::push(std::vector<unsigned char>)' at <source>:12:21: /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_algobase.h:452:30: warning: 'void* __builtin_memcpy(void*, const void*, long unsigned int)' writing between 2 and 9223372036854775807 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=] 452 | __builtin_memmove(__result, __first, sizeof(_Tp) * _Num); | ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/x86_64-linux-gnu/bits/c++allocator.h:33, from /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/allocator.h:46, from /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/vector:63: In member function '_Tp* std::__new_allocator<_Tp>::allocate(size_type, const void*) [with _Tp = unsigned char]', inlined from 'static _Tp* std::allocator_traits<std::allocator<_Tp1> >::allocate(allocator_type&, size_type) [with _Tp = unsigned char]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/alloc_traits.h:478:28, inlined from 'std::_Vector_base<_Tp, _Alloc>::pointer std::_Vector_base<_Tp, _Alloc>::_M_allocate(std::size_t) [with _Tp = unsigned char; _Alloc = std::allocator<unsigned char>]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_vector.h:380:33, inlined from 'void std::vector<_Tp, _Alloc>::_M_range_insert(iterator, _ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = __gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char> >; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/vector.tcc:1013:40, inlined from 'std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(const_iterator, _InputIterator, _InputIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char> >; <template-parameter-2-2> = void; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_vector.h:1488:19, inlined from 'void buffer::push(std::vector<unsigned char>)' at <source>:12:21: /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/new_allocator.h:151:55: note: at offset [-9223372036854775808, -1] into destination object of size [1, 9223372036854775807] allocated by 'operator new' 151 | return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp))); | ^ Compiler returned: 0