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