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
  • [Bug c++/121280] New: [15/16 R... ryan.stocks00 at gmail dot com via Gcc-bugs

Reply via email to