diff --git a/include/boost/endian/buffers.hpp b/include/boost/endian/buffers.hpp index a9095ac..081aee8 100644 --- a/include/boost/endian/buffers.hpp +++ b/include/boost/endian/buffers.hpp @@ -38,6 +38,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -221,20 +225,27 @@ namespace endian { typedef unrolled_byte_loops next; + // shifting a negative number is flagged by -fsanitize=undefined + // so use the corresponding unsigned type for the shifts + + typedef typename boost::conditional< + boost::is_integral::value, + boost::make_unsigned, boost::type_identity >::type::type U; + static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT - { return static_cast(*(bytes - 1) | (next::load_big(bytes - 1) << 8)); } + { return static_cast(*(bytes - 1) | (static_cast(next::load_big(bytes - 1)) << 8)); } static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT - { return static_cast(*bytes | (next::load_little(bytes + 1) << 8)); } + { return static_cast(*bytes | (static_cast(next::load_little(bytes + 1)) << 8)); } static void store_big(char* bytes, T value) BOOST_NOEXCEPT { *(bytes - 1) = static_cast(value); - next::store_big(bytes - 1, static_cast(value >> 8)); + next::store_big(bytes - 1, static_cast(static_cast(value) >> 8)); } static void store_little(char* bytes, T value) BOOST_NOEXCEPT { *bytes = static_cast(value); - next::store_little(bytes + 1, static_cast(value >> 8)); + next::store_little(bytes + 1, static_cast(static_cast(value) >> 8)); } };