https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121280
Bug ID: 121280 Summary: [15/16 Regression] False positive array-bounds warning with O3 and std::vector.back() of a local vector copy Product: gcc Version: 15.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ryan.stocks00 at gmail dot com Target Milestone: --- The following code ```cpp #include <vector> void vector_func_1(std::vector<int>& vect) { std::vector<int> vect_copy = vect; if (vect.front() < vect.back()) { vect_copy.front() = vect_copy.back(); } vect = vect_copy; } void vector_func_2(std::vector<int>& vect) { std::vector<int> vect_copy = vect; if (vect_copy.front() < vect_copy.back()) { vect_copy.front() = vect_copy.back(); } vect = vect_copy; } ``` when compiled with `g++ -O3 -Wall` gives the following warning: ``` <source>: In function 'void vector_func_2(std::vector<int>&)': <source>:15:43: warning: array subscript -1 is outside array bounds of 'int [2305843009213693951]' [-Warray-bounds=] 15 | if (vect_copy.front() < vect_copy.back()) { | ~~~~~~~~~~~~~~^~ In file included from /opt/compiler-explorer/gcc-15.1.0/include/c++/15.1.0/x86_64-linux-gnu/bits/c++allocator.h:33, from /opt/compiler-explorer/gcc-15.1.0/include/c++/15.1.0/bits/allocator.h:46, from /opt/compiler-explorer/gcc-15.1.0/include/c++/15.1.0/vector:65, from <source>:1: In member function '_Tp* std::__new_allocator<_Tp>::allocate(size_type, const void*) [with _Tp = int]', inlined from 'static _Tp* std::allocator_traits<std::allocator<_Tp1> >::allocate(allocator_type&, size_type) [with _Tp = int]' at /opt/compiler-explorer/gcc-15.1.0/include/c++/15.1.0/bits/alloc_traits.h:614:28, inlined from 'std::_Vector_base<_Tp, _Alloc>::pointer std::_Vector_base<_Tp, _Alloc>::_M_allocate(std::size_t) [with _Tp = int; _Alloc = std::allocator<int>]' at /opt/compiler-explorer/gcc-15.1.0/include/c++/15.1.0/bits/stl_vector.h:387:33, inlined from 'void std::_Vector_base<_Tp, _Alloc>::_M_create_storage(std::size_t) [with _Tp = int; _Alloc = std::allocator<int>]' at /opt/compiler-explorer/gcc-15.1.0/include/c++/15.1.0/bits/stl_vector.h:405:44, inlined from 'std::_Vector_base<_Tp, _Alloc>::_Vector_base(std::size_t, const allocator_type&) [with _Tp = int; _Alloc = std::allocator<int>]' at /opt/compiler-explorer/gcc-15.1.0/include/c++/15.1.0/bits/stl_vector.h:341:26, inlined from 'std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = int; _Alloc = std::allocator<int>]' at /opt/compiler-explorer/gcc-15.1.0/include/c++/15.1.0/bits/stl_vector.h:633:61, inlined from 'void vector_func_2(std::vector<int>&)' at <source>:14:34: /opt/compiler-explorer/gcc-15.1.0/include/c++/15.1.0/bits/new_allocator.h:151:73: note: at offset -4 into object of size [1, 9223372036854775804] allocated by 'operator new' 151 | return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp))); | ^ Compiler returned: 0 ``` Of particular interest is that the first function does not yield a warning whilst the second does. This occurs with GCC 15.1.1 as well as the current master branch of gcc (16.0.0) but does not occur with gcc 14.3 The error only occurs at the O3 level of optimization. Here is a godbolt example that replicates the error https://godbolt.org/z/qseraore9