https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124662

            Bug ID: 124662
           Summary: Warning on valid vector initialization and push_back
                    combination.
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: hill.harry.r at gmail dot com
  Target Milestone: ---

The following code,

```
#include <vector>

std::vector<double>
getVector(bool add_element)
{
    std::vector<double> x = { 0, 0 };
    if (add_element) {
        x.push_back(0);
    }
    return x;
}

int
main(int argc, char** argv)
{
    std::vector<double> const x = getVector(false);
    return x.size();
}
```

when compiling with,

```
-O3
-std=c++20
-Wall
-fno-delete-null-pointer-checks
```

emits a warning, so fails to compile with -Werror. First appears in gcc-12.1,
is present up to trunk as of today on godbolt. The warning doesn't happen at
O1, but does at O2 & O3. Output from trunk compilation is,


```
In file included from
/cefs/a2/a29ece5e0489c45a9a48ace3_gcc-trunk-20260327/include/c++/16.0.1/bits/stl_iterator.h:78,
                 from
/cefs/a2/a29ece5e0489c45a9a48ace3_gcc-trunk-20260327/include/c++/16.0.1/bits/stl_algobase.h:66,
                 from
/cefs/a2/a29ece5e0489c45a9a48ace3_gcc-trunk-20260327/include/c++/16.0.1/vector:64,
                 from <source>:1:
In function 'constexpr _Tp* std::construct_at(_Tp*, _Args&& ...) [with _Tp =
double; _Args = {double}]',
    inlined from 'static constexpr void
std::allocator_traits<std::allocator<_Up> >::construct(allocator_type&, _Up*,
_Args&& ...) [with _Up = double; _Args = {double}; _Tp = double]' at
/cefs/a2/a29ece5e0489c45a9a48ace3_gcc-trunk-20260327/include/c++/16.0.1/bits/alloc_traits.h:716:21,
    inlined from 'constexpr std::vector<_Tp, _Alloc>::reference
std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {double}; _Tp
= double; _Alloc = std::allocator<double>]' at
/cefs/a2/a29ece5e0489c45a9a48ace3_gcc-trunk-20260327/include/c++/16.0.1/bits/vector.tcc:121:30,
    inlined from 'constexpr void std::vector<_Tp,
_Alloc>::push_back(value_type&&) [with _Tp = double; _Alloc =
std::allocator<double>]' at
/cefs/a2/a29ece5e0489c45a9a48ace3_gcc-trunk-20260327/include/c++/16.0.1/bits/stl_vector.h:1424:21,
    inlined from 'std::vector<double> getVector(bool)' at <source>:8:20:
/cefs/a2/a29ece5e0489c45a9a48ace3_gcc-trunk-20260327/include/c++/16.0.1/bits/stl_construct.h:110:16:
error: array subscript 2 is outside array bounds of 'double [2]'
[-Werror=array-bounds=]
  110 |         return ::new(__loc) _Tp(std::forward<_Args>(__args)...);
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from
/cefs/a2/a29ece5e0489c45a9a48ace3_gcc-trunk-20260327/include/c++/16.0.1/x86_64-linux-gnu/bits/c++allocator.h:33,
                 from
/cefs/a2/a29ece5e0489c45a9a48ace3_gcc-trunk-20260327/include/c++/16.0.1/bits/allocator.h:46,
                 from
/cefs/a2/a29ece5e0489c45a9a48ace3_gcc-trunk-20260327/include/c++/16.0.1/vector:65:
In member function 'constexpr _Tp*
std::__new_allocator<_Tp>::allocate(size_type, const void*) [with _Tp =
double]',
    inlined from 'constexpr _Tp* std::allocator< <template-parameter-1-1>
>::allocate(std::size_t) [with _Tp = double]' at
/cefs/a2/a29ece5e0489c45a9a48ace3_gcc-trunk-20260327/include/c++/16.0.1/bits/allocator.h:206:40,
    inlined from 'static constexpr _Tp*
std::allocator_traits<std::allocator<_Up> >::allocate(allocator_type&,
size_type) [with _Tp = double]' at
/cefs/a2/a29ece5e0489c45a9a48ace3_gcc-trunk-20260327/include/c++/16.0.1/bits/alloc_traits.h:638:28,
    inlined from 'constexpr std::_Vector_base<_Tp, _Alloc>::pointer
std::_Vector_base<_Tp, _Alloc>::_M_allocate(std::size_t) [with _Tp = double;
_Alloc = std::allocator<double>]' at
/cefs/a2/a29ece5e0489c45a9a48ace3_gcc-trunk-20260327/include/c++/16.0.1/bits/stl_vector.h:389:33,
    inlined from 'constexpr void std::vector<_Tp,
_Alloc>::_M_range_initialize_n(_Iterator, _Sentinel, size_type) [with _Iterator
= const double*; _Sentinel = const double*; _Tp = double; _Alloc =
std::allocator<double>]' at
/cefs/a2/a29ece5e0489c45a9a48ace3_gcc-trunk-20260327/include/c++/16.0.1/bits/stl_vector.h:1975:23,
    inlined from 'constexpr std::vector<_Tp,
_Alloc>::vector(std::initializer_list<_Tp>, const allocator_type&) [with _Tp =
double; _Alloc = std::allocator<double>]' at
/cefs/a2/a29ece5e0489c45a9a48ace3_gcc-trunk-20260327/include/c++/16.0.1/bits/stl_vector.h:702:23,
    inlined from 'std::vector<double> getVector(bool)' at <source>:6:36:
/cefs/a2/a29ece5e0489c45a9a48ace3_gcc-trunk-20260327/include/c++/16.0.1/bits/new_allocator.h:162:75:
note: at offset 16 into object of size 16 allocated by 'operator new'
  162 |           return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n *
sizeof(_Tp)));
      |                                                                        
  ^
cc1plus: all warnings being treated as errors
Compiler returned: 1
```

Has some similarities to 
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120727
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107927

Reply via email to