https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111273
Bug ID: 111273 Summary: Spurious array-bounds error when copying data using _GLIBCXX_DEBUG iterators Product: gcc Version: 13.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: jgrossma at qti dot qualcomm.com Target Milestone: --- When compiling with -Warray-bounds and -D_GLIBCXX_DEBUG on g++ 13.2.0, copying from a vector to an array throws the Warray-bounds error during compilation. Source: #include <vector> #include <array> #include <algorithm> static const int N = 1; int func(std::vector<int> const &v) { std::array<int, N> a; std::copy_n(v.begin(), N, a.begin()); return a[0]; } Program should not have any problems at compile time. Copies 1 location to a 1 element array. Changing N=2 doesn't show the error. Compile options: -Werror -O3 -Warray-bounds -D_GLIBCXX_DEBUG -std=c++20 Disabling -D_GLIBCXX_DEBUG doesn't show the error. Output: --- In file included from /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.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 = const int; _Up = int; bool _IsMove = false]', inlined from 'constexpr _OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = const int*; _OI = int*]' at /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_algobase.h:506:30, inlined from 'constexpr _OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove = false; _II = const int*; _OI = int*]' at /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_algobase.h:533:42, inlined from 'constexpr _OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = __gnu_cxx::__normal_iterator<const int*, __cxx1998::vector<int, allocator<int> > >; _OI = int*]' at /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_algobase.h:540:31, inlined from '_OI std::__copy_move_a(const __gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&, const __gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&, _OI) [with bool _IsMove = false; _Ite = __gnu_cxx::__normal_iterator<const int*, __cxx1998::vector<int, allocator<int> > >; _Seq = __debug::vector<int>; _Cat = random_access_iterator_tag; _OI = int*]' at /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/debug/safe_iterator.tcc:257:36, inlined from 'constexpr _OI std::copy(_II, _II, _OI) [with _II = __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<const int*, __cxx1998::vector<int, allocator<int> > >, __debug::vector<int>, random_access_iterator_tag>; _OI = int*]' at /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_algobase.h:633:7, inlined from 'constexpr _OutputIterator std::__copy_n(_RandomAccessIterator, _Size, _OutputIterator, random_access_iterator_tag) [with _RandomAccessIterator = __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<const int*, __cxx1998::vector<int, allocator<int> > >, __debug::vector<int>, random_access_iterator_tag>; _Size = int; _OutputIterator = int*]' at /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_algo.h:731:23, inlined from 'constexpr _OIter std::copy_n(_IIter, _Size, _OIter) [with _IIter = __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<const int*, __cxx1998::vector<int, allocator<int> > >, __debug::vector<int>, random_access_iterator_tag>; _Size = int; _OIter = int*]' at /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_algo.h:763:27, inlined from 'int func(const std::__debug::vector<int>&)' at <source>:9:16: /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_algobase.h:437:30: error: 'void* __builtin_memcpy(void*, const void*, long unsigned int)' forming offset 4 is out of the bounds [0, 4] of object 'a' with type 'std::array<int, 1>' [-Werror=array-bounds=] 437 | __builtin_memmove(__result, __first, sizeof(_Tp) * _Num); | ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <source>: In function 'int func(const std::__debug::vector<int>&)': <source>:8:24: note: 'a' declared here 8 | std::array<int, N> a; | ^ cc1plus: all warnings being treated as errors Compiler returned: 1 --- Interestingly, the error location should not even be hit for a 1 element copy as it's inside a check for length>1. Godbolt link shows as well: https://godbolt.org/z/v8GK4nzde GCC 12 does not seem to show this issue. Seems related to this one: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107852