Skip to content

gcc 13.2.0: bogus copy warning (with default optimizations only) #1538

Open
@evoskuil

Description

@evoskuil
template <size_t Start, size_t End, size_t Size,
    if_not_greater<Start, Size>, if_not_greater<End, Size>,
    if_not_lesser<End, Start>>
constexpr data_array<End - Start> slice(const data_array<Size>& bytes) NOEXCEPT
{
    data_array<End - Start> out;
    const auto beg = std::next(bytes.begin(), Start);
    const auto end = std::next(bytes.begin(), End);
    std::copy(beg, end, out.begin());
    return out;
}

In relation to the code above, the warnings below indicate that

Start = 0
End = 1
Size = 25

and

forming offset 1 is out of the bounds [0, 1] of object 'out' with type 'libbitcoin::system::data_array<1>' {aka 'std::array<unsigned char, 1>'}

This is a bogus warning. Iteration from element 0 to 1 of a 25 element array implies the copy of one element. The target is the first element of a single element array of the same type as the source. The end element of a std container is not required to be allocated and always has the same position as size (one past the last element).

The warning goes away under -O3.

In file included from /usr/include/c++/13/string:51,
                 from /usr/include/c++/13/bits/locale_classes.h:40,
                 from /usr/include/c++/13/bits/ios_base.h:41,
                 from /usr/include/c++/13/ios:44,
                 from /usr/include/c++/13/ostream:40,
                 from /usr/include/c++/13/iostream:41,
                 from ./include/bitcoin/system/wallet/addresses/payment_address.hpp:22,
                 from src/wallet/addresses/payment_address.cpp:19:
In static member function 'static constexpr _Up* std::__copy_move<_IsMove, true, std::random_access_iterator_tag>::__copy_m(_Tp*, _Tp*, _Up*) [with _Tp = const unsigned char; _Up = unsigned char; bool _IsMove = false]',
    inlined from 'constexpr _OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = const unsigned char*; _OI = unsigned char*]' at /usr/include/c++/13/bits/stl_algobase.h:506:30,
    inlined from 'constexpr _OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove = false; _II = const unsigned char*; _OI = unsigned char*]' at /usr/include/c++/13/bits/stl_algobase.h:533:42,
    inlined from 'constexpr _OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = const unsigned char*; _OI = unsigned char*]' at /usr/include/c++/13/bits/stl_algobase.h:540:31,
    inlined from 'constexpr _OI std::copy(_II, _II, _OI) [with _II = const unsigned char*; _OI = unsigned char*]' at /usr/include/c++/13/bits/stl_algobase.h:633:7,
    inlined from 'constexpr libbitcoin::system::data_array<(End - Start)> libbitcoin::system::slice(data_array<Size>&) [with long unsigned int Start = 0; long unsigned int End = 1; long unsigned int Size = 25; typename std::enable_if<(!(Start > Size)), bool>::type <anonymous> = true; typename std::enable_if<(!(End > Size)), bool>::type <anonymous> = true; typename std::enable_if<(!(End < Start)), bool>::type <anonymous> = true]' at ./include/bitcoin/system/impl/data/data_array.ipp:106:14,
    inlined from 'libbitcoin::system::wallet::checked<Prefix, Payload, Checksum>::prefix_type libbitcoin::system::wallet::checked<Prefix, Payload, Checksum>::prefix() const [with long unsigned int Prefix = 1; long unsigned int Payload = 20; long unsigned int Checksum = 4]' at ./include/bitcoin/system/impl/wallet/addresses/checked.ipp:103:31,
    inlined from 'uint8_t libbitcoin::system::wallet::payment_address::prefix() const' at src/wallet/addresses/payment_address.cpp:156:27:
/usr/include/c++/13/bits/stl_algobase.h:437:30: warning: 'void* __builtin_memcpy(void*, const void*, long unsigned int)' forming offset 1 is out of the bounds [0, 1] of object 'out' with type 'libbitcoin::system::data_array<1>' {aka 'std::array<unsigned char, 1>'} [-Warray-bounds=]
  437 |             __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
      |             ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ./include/bitcoin/system/data/data_array.hpp:110,
                 from ./include/bitcoin/system/data/data.hpp:25,
                 from ./include/bitcoin/system/chain/checkpoint.hpp:25,
                 from ./include/bitcoin/system/chain/chain_state.hpp:24,
                 from ./include/bitcoin/system/chain/header.hpp:26,
                 from ./include/bitcoin/system/chain/block.hpp:26,
                 from ./include/bitcoin/system/chain/chain.hpp:22,
                 from ./include/bitcoin/system/wallet/addresses/payment_address.hpp:26:
./include/bitcoin/system/impl/data/data_array.ipp: In member function 'uint8_t libbitcoin::system::wallet::payment_address::prefix() const':
./include/bitcoin/system/impl/data/data_array.ipp:103:29: note: 'out' declared here
  103 |     data_array<End - Start> out;
      |                             ^~~
In static member function 'static constexpr _Up* std::__copy_move<_IsMove, true, std::random_access_iterator_tag>::__copy_m(_Tp*, _Tp*, _Up*) [with _Tp = const unsigned char; _Up = unsigned char; bool _IsMove = false]',
    inlined from 'constexpr _OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = const unsigned char*; _OI = unsigned char*]' at /usr/include/c++/13/bits/stl_algobase.h:506:30,
    inlined from 'constexpr _OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove = false; _II = const unsigned char*; _OI = unsigned char*]' at /usr/include/c++/13/bits/stl_algobase.h:533:42,
    inlined from 'constexpr _OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = const unsigned char*; _OI = unsigned char*]' at /usr/include/c++/13/bits/stl_algobase.h:540:31,
    inlined from 'constexpr _OI std::copy(_II, _II, _OI) [with _II = const unsigned char*; _OI = unsigned char*]' at /usr/include/c++/13/bits/stl_algobase.h:633:7,
    inlined from 'constexpr libbitcoin::system::data_array<(End - Start)> libbitcoin::system::slice(data_array<Size>&) [with long unsigned int Start = 0; long unsigned int End = 1; long unsigned int Size = 25; typename std::enable_if<(!(Start > Size)), bool>::type <anonymous> = true; typename std::enable_if<(!(End > Size)), bool>::type <anonymous> = true; typename std::enable_if<(!(End < Start)), bool>::type <anonymous> = true]' at ./include/bitcoin/system/impl/data/data_array.ipp:106:14,
    inlined from 'libbitcoin::system::wallet::checked<Prefix, Payload, Checksum>::prefix_type libbitcoin::system::wallet::checked<Prefix, Payload, Checksum>::prefix() const [with long unsigned int Prefix = 1; long unsigned int Payload = 20; long unsigned int Checksum = 4]' at ./include/bitcoin/system/impl/wallet/addresses/checked.ipp:103:31,
    inlined from 'uint8_t libbitcoin::system::wallet::payment_address::prefix() const' at src/wallet/addresses/payment_address.cpp:156:27,
    inlined from 'libbitcoin::system::chain::script libbitcoin::system::wallet::payment_address::output_script() const' at src/wallet/addresses/payment_address.cpp:166:19:
/usr/include/c++/13/bits/stl_algobase.h:437:30: warning: 'void* __builtin_memcpy(void*, const void*, long unsigned int)' forming offset 1 is out of the bounds [0, 1] of object 'out' with type 'libbitcoin::system::data_array<1>' {aka 'std::array<unsigned char, 1>'} [-Warray-bounds=]
  437 |             __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
      |             ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/bitcoin/system/impl/data/data_array.ipp: In member function 'libbitcoin::system::chain::script libbitcoin::system::wallet::payment_address::output_script() const':
./include/bitcoin/system/impl/data/data_array.ipp:103:29: note: 'out' declared here
  103 |     data_array<End - Start> out;
      |                             ^~~

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions