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

            Bug ID: 120727
           Summary: Bogus -Warray-bounds on std::vector::push_back() with
                    -O2
           Product: gcc
           Version: 15.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: boris at kolpackov dot net
  Target Milestone: ---

Given the following code fragment:

vector<CK_ATTRIBUTE> sa ({{CKA_CLASS,    &oc, sizeof (oc)},
                         {CKA_KEY_TYPE, &kt, sizeof (kt)}});
if (idn.id)
  sa.push_back (
    CK_ATTRIBUTE {CKA_ID,
                  const_cast<unsigned char*> (idn.id->data ()),
                  idn.id->size ()});

I get the following bogus warning starting with GCC 15.1.0:

In function ‘constexpr _Tp* std::construct_at(_Tp*, _Args&& ...) [with _Tp =
_CK_ATTRIBUTE; _Args = {_CK_ATTRIBUTE}]’,
    inlined from ‘static constexpr void
std::allocator_traits<std::allocator<_Up> >::construct(allocator_type&, _Up*,
_Args&& ...) [with _Up = _CK_ATTRIBUTE; _Args = {_CK_ATTRIBUTE}; _Tp =
_CK_ATTRIBUTE]’ at /usr/include/c++/15/bits/alloc_traits.h:676:21,
    inlined from ‘constexpr std::vector<_Tp, _Alloc>::reference
std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args =
{_CK_ATTRIBUTE}; _Tp = _CK_ATTRIBUTE; _Alloc = std::allocator<_CK_ATTRIBUTE>]’
at /usr/include/c++/15/bits/vector.tcc:117:30,
    inlined from ‘constexpr void std::vector<_Tp,
_Alloc>::push_back(value_type&&) [with _Tp = _CK_ATTRIBUTE; _Alloc =
std::allocator<_CK_ATTRIBUTE>]’ at
/usr/include/c++/15/bits/stl_vector.h:1434:21,
    inlined from ‘openssl::agent::pkcs11::private_key::private_key(const
openssl::agent::pkcs11::identity&, const openssl::agent::pkcs11::access&, const
char*, std::optional<openssl::simulate_outcome>)’ at
/tmp/build/openssl-agent-0.18.0-a.0.20250421094510.132268ea8637/openssl/agent/pkcs11/private-key.cxx:312:26:
/usr/include/c++/15/bits/stl_construct.h:110:16: error: array subscript 2 is
outside array bounds of ‘_CK_ATTRIBUTE [2]’ [-Werror=array-bounds=]
  110 |         return ::new(__loc) _Tp(std::forward<_Args>(__args)...);
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from
/usr/include/c++/15/x86_64-redhat-linux/bits/c++allocator.h:33,
                 from /usr/include/c++/15/bits/allocator.h:46,
                 from /usr/include/c++/15/vector:65:
In member function ‘_Tp* std::__new_allocator<_Tp>::allocate(size_type, const
void*) [with _Tp = _CK_ATTRIBUTE]’,
    inlined from ‘constexpr _Tp* std::allocator< <template-parameter-1-1>
>::allocate(std::size_t) [with _Tp = _CK_ATTRIBUTE]’ at
/usr/include/c++/15/bits/allocator.h:203:40,
    inlined from ‘static constexpr _Tp*
std::allocator_traits<std::allocator<_Up> >::allocate(allocator_type&,
size_type) [with _Tp = _CK_ATTRIBUTE]’ at
/usr/include/c++/15/bits/alloc_traits.h:614:28,
    inlined from ‘constexpr std::_Vector_base<_Tp, _Alloc>::pointer
std::_Vector_base<_Tp, _Alloc>::_M_allocate(std::size_t) [with _Tp =
_CK_ATTRIBUTE; _Alloc = std::allocator<_CK_ATTRIBUTE>]’ at
/usr/include/c++/15/bits/stl_vector.h:387:33,
    inlined from ‘constexpr void std::vector<_Tp,
_Alloc>::_M_range_initialize_n(_Iterator, _Sentinel, size_type) [with _Iterator
= const _CK_ATTRIBUTE*; _Sentinel = const _CK_ATTRIBUTE*; _Tp = _CK_ATTRIBUTE;
_Alloc = std::allocator<_CK_ATTRIBUTE>]’ at
/usr/include/c++/15/bits/stl_vector.h:1985:23,
    inlined from ‘constexpr std::vector<_Tp,
_Alloc>::vector(std::initializer_list<_Tp>, const allocator_type&) [with _Tp =
_CK_ATTRIBUTE; _Alloc = std::allocator<_CK_ATTRIBUTE>]’ at
/usr/include/c++/15/bits/stl_vector.h:712:23,
    inlined from ‘openssl::agent::pkcs11::private_key::private_key(const
openssl::agent::pkcs11::identity&, const openssl::agent::pkcs11::access&, const
char*, std::optional<openssl::simulate_outcome>)’ at
/tmp/build/openssl-agent-0.18.0-a.0.20250421094510.132268ea8637/openssl/agent/pkcs11/private-key.cxx:310:70:
/usr/include/c++/15/bits/new_allocator.h:151:73: note: at offset 48 into object
of size 48 allocated by ‘operator new’
  151 |         return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n *
sizeof(_Tp)));
      |                                                                        
^

The partially preprocessed translation unit is attached. To reproduce, compile
like so:

g++ -Wall -O2 -std=c++26 -c -fdirectives-only private-key.ii

Reply via email to