libbitcoin / libbitcoin-system

Bitcoin Cross-Platform C++ Development Toolkit
https://libbitcoin.info/
Other
1.3k stars 384 forks source link

gcc 13.2.0: bogus Wstringop-overflow in bit_writer (-O3 only) #1539

Open evoskuil opened 4 weeks ago

evoskuil commented 4 weeks ago
template <typename Value, if_integral_integer<Value>>
constexpr void set_left_into(Value& target, size_t offset, bool state) NOEXCEPT
{
    const auto bit = bit_left<Value>(offset);
    state ? target |= bit : target &= bit_not(bit);
}

Gcc warns:

warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]

state ? target |= bit : target &= bit_not(bit);

Yet Value is integral integer and bit, target, bit_left<Value> and bit_not<Value> are all typed as Value.

The warning does not occur under default optimizations.

In file included from ./include/bitcoin/system/math/bits.hpp:226,
                 from ./include/bitcoin/system/impl/math/power.ipp:23,
                 from ./include/bitcoin/system/math/power.hpp:60,
                 from ./include/bitcoin/system/math/limits.hpp:23,
                 from ./include/bitcoin/system/impl/math/addition.ipp:23,
                 from ./include/bitcoin/system/math/addition.hpp:116,
                 from ./include/bitcoin/system/math/math.hpp:22,
                 from ./include/bitcoin/system/data/array_cast.hpp:23,
                 from ./include/bitcoin/system/data/data.hpp:22,
                 from ./include/bitcoin/system/crypto/golomb_coding.hpp:27,
                 from src/crypto/golomb_coding.cpp:22:
In function 'constexpr void libbitcoin::system::set_left_into(Value&, size_t, bool) [with Value = unsigned char; typename std::enable_if<is_integral_integer<Type>, bool>::type <anonymous> = true]',
    inlined from 'void libbitcoin::system::bit_writer<OStream>::write_bit(bool) [with OStream = std::basic_ostream<char>]' at ./include/bitcoin/system/impl/stream/streamers/bit_writer.ipp:59:18,
    inlined from 'void libbitcoin::system::golomb::encode(libbitcoin::system::bitwriter&, uint64_t, uint8_t)' at src/crypto/golomb_coding.cpp:42:23,
    inlined from 'void libbitcoin::system::golomb::construct(libbitcoin::system::bitwriter&, const libbitcoin::system::data_stack&, uint8_t, const libbitcoin::system::siphash_key&, uint64_t)' at src/crypto/golomb_coding.cpp:97:15,
    inlined from 'void libbitcoin::system::golomb::construct(std::ostream&, const libbitcoin::system::data_stack&, uint8_t, const libbitcoin::system::siphash_key&, uint64_t)' at src/crypto/golomb_coding.cpp:130:14:
./include/bitcoin/system/impl/math/bits.ipp:147:20: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  147 |     state ? target |= bit : target &= bit_not(bit);
      |             ~~~~~~~^~~~~~
In file included from ./include/bitcoin/system/stream/streamers/bit_flipper.hpp:28,
                 from ./include/bitcoin/system/stream/stream.hpp:33,
                 from src/crypto/golomb_coding.cpp:31:
./include/bitcoin/system/stream/streamers/bit_writer.hpp: In function 'void libbitcoin::system::golomb::construct(std::ostream&, const libbitcoin::system::data_stack&, uint8_t, const libbitcoin::system::siphash_key&, uint64_t)':
./include/bitcoin/system/stream/streamers/bit_writer.hpp:39:7: note: at offset [16, 24] into destination object 'libbitcoin::system::bit_writer<std::basic_ostream<char> >::<anonymous>' of size 8
   39 | class bit_writer
      |       ^~~~~~~~~~
In function 'constexpr void libbitcoin::system::set_left_into(Value&, size_t, bool) [with Value = unsigned char; typename std::enable_if<is_integral_integer<Type>, bool>::type <anonymous> = true]',
    inlined from 'void libbitcoin::system::bit_writer<OStream>::write_bit(bool) [with OStream = std::basic_ostream<char>]' at ./include/bitcoin/system/impl/stream/streamers/bit_writer.ipp:59:18,
    inlined from 'void libbitcoin::system::golomb::encode(libbitcoin::system::bitwriter&, uint64_t, uint8_t)' at src/crypto/golomb_coding.cpp:44:19,
    inlined from 'void libbitcoin::system::golomb::construct(libbitcoin::system::bitwriter&, const libbitcoin::system::data_stack&, uint8_t, const libbitcoin::system::siphash_key&, uint64_t)' at src/crypto/golomb_coding.cpp:97:15,
    inlined from 'void libbitcoin::system::golomb::construct(std::ostream&, const libbitcoin::system::data_stack&, uint8_t, const libbitcoin::system::siphash_key&, uint64_t)' at src/crypto/golomb_coding.cpp:130:14:
./include/bitcoin/system/impl/math/bits.ipp:147:36: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  147 |     state ? target |= bit : target &= bit_not(bit);
      |                             ~~~~~~~^~~~~~~~~~~~~~~
./include/bitcoin/system/stream/streamers/bit_writer.hpp: In function 'void libbitcoin::system::golomb::construct(std::ostream&, const libbitcoin::system::data_stack&, uint8_t, const libbitcoin::system::siphash_key&, uint64_t)':
./include/bitcoin/system/stream/streamers/bit_writer.hpp:39:7: note: at offset [16, 24] into destination object 'libbitcoin::system::bit_writer<std::basic_ostream<char> >::<anonymous>' of size 8
   39 | class bit_writer
      |       ^~~~~~~~~~
cc1plus: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
./include/bitcoin/system/stream/streamers/bit_writer.hpp:39:7: note: at offset [16, 24] into destination object 'libbitcoin::system::bit_writer<std::basic_ostream<char> >::<anonymous>' of size 8
evoskuil commented 4 weeks ago

See our gcc12 bogus Wstringop-overflow warnings that are now gone in gcc 13.