Search code examples
c++gccboostclangbigint

AddressSanitizer: stack-buffer-overflow on boost cpp_int


I have the following code sample that should convert std::array<uint8_t> to BigInt i.e. boost::multiprecision::cpp_int. I compile this code with clang64 15.0.7 (С++17) from MSYS2. Code works fine and converts array of uint8_t to BigInt.

#include <string>
#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>

using BigInt = boost::multiprecision::cpp_int;

const auto b = std::array<uint8_t, 16>{
    0x11, 0x22, 0x33, 0x44,
    0x11, 0x22, 0x33, 0x44,
    0x11, 0x22, 0x33, 0x44,
    0x11, 0x22, 0x33, 0x44
};

int main() {
    size_t shift = 0;
    auto initial = BigInt{};

    auto i = std::accumulate(
            b.cbegin(),
            b.cend(),
            initial,
            [&shift](const BigInt &acc, uint8_t it) {
                auto byte = BigInt{it};
                auto result = acc | (byte << shift);
                shift += CHAR_BIT;
                return result;
            }
    );

    std::cout << "Boost integer " << i << std::endl;
}

But when I added ASAN options to my CMakeFile:

add_compile_options(-fsanitize=address -fsanitize=undefined)
add_link_options(-fsanitize=address -fsanitize=undefined)

Code crashed with the log below. I also found boost cpp_int stack unwind crash but this issue valid only for GCC 7.1/8.1 and was not confirmed for clang. Besides crashes like these occurred under ASAN on 'simple' "boost" expressions for cpp_int (for GCC 7.3.3), e.g. m_state = (data ^ key) & mask; with all items are cpp_int. What am I doing wrong with this cpp_int?

==8032==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x00f79ccfed58 at pc 0x7ff60fb5fb02 bp 0x00f79ccfe200 sp 0x00f79ccfe248
READ of size 8 at 0x00f79ccfed58 thread T0
    #0 0x7ff60fb5fb01 in void boost::multiprecision::backends::left_shift_byte<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>>(boost::multiprecision::backe
nds::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>&, unsigned __int128) C:/msys64/clang64/include/boost/multiprecision/cpp_int/bitwise.hpp:334:25
    #1 0x7ff60fb5f314 in std::__1::enable_if<!is_trivial_cpp_int<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>>::value, void>::type boost::multiprecision:
:backends::eval_left_shift<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>(boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::c
pp_int_check_type)0, std::__1::allocator<unsigned long long>>&, unsigned __int128) C:/msys64/clang64/include/boost/multiprecision/cpp_int/bitwise.hpp:500:7
    #2 0x7ff60fb5f002 in void boost::multiprecision::default_ops::eval_left_shift<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, boost::multiprecision::ba
ckends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, unsigned long long>(boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost:
:multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>&, boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>> const&, unsigned long long
) C:/msys64/clang64/include/boost/multiprecision/detail/default_ops.hpp:890:4
    #3 0x7ff60fb5ed30 in void boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_opt
ion)1>::do_assign_left_shift<boost::multiprecision::detail::expression<boost::multiprecision::detail::terminal, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__
1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, void, void, void>, unsigned long long>(boost::multiprecision::detail::expression<boost::multiprecision::detail::terminal, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ul
l, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, void, void, void> const&, unsigned long long const&, boost::multiprecision::detail::terminal const&) C:/msys64
/clang64/include/boost/multiprecision/number.hpp:1665:7
    #4 0x7ff60fb5964a in void boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_opt
ion)1>::do_assign<boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::alloca
tor<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>>(boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::mu
ltiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void> const&, boost::multiprecision::detail::shift_left const&) C:/msys64/clang64/include/boost/m
ultiprecision/number.hpp:1616:7
    #5 0x7ff60fb5a979 in void boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_opt
ion)1>::do_assign<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multipre
cision::expression_template_option)1>, unsigned long long, void, void>(boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::m
ultiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void> const&, std::__1::integral_constant<bool, true> const&) C:/msys64/clang64/include/boost/multiprecision/number.hpp:1222:7
    #6 0x7ff60fb5a719 in std::__1::enable_if<std::is_convertible<boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multipr
ecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>::result_type, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer
_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>>::value, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boos
t::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>&>::type boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecisi
on::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>::operator=<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integ
er_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>(boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number
<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void> const&) C:/msys64/c
lang64/include/boost/multiprecision/number.hpp:319:7
    #7 0x7ff60fb5a2db in boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1
>::number<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::
expression_template_option)1>, unsigned long long, void, void>(boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprec
ision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void> const&, std::__1::enable_if<std::is_convertible<boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::mu
ltiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>
::result_type, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>>::value,
 void>::type*) C:/msys64/clang64/include/boost/multiprecision/number.hpp:440:13
    #8 0x7ff60fb58d7d in void boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_opt
ion)1>::do_bitwise_or<boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::al
locator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>, boost::multiprecision::detail::shift_left>(boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::b
ackends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void> const&, boost::multiprecision::detail::shift
_left const&) C:/msys64/clang64/include/boost/multiprecision/number.hpp:2116:17
    #9 0x7ff60fb57f63 in void boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_opt
ion)1>::do_assign<boost::multiprecision::detail::expression<boost::multiprecision::detail::bitwise_or, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::alloca
tor<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1,
 (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>, void, void>>(boost::multiprecision::detail::expression<boost::multiprecision::detail::bitwise_or, boost::multiprecision::nu
mber<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::detail::expression<boost
::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_temp
late_option)1>, unsigned long long, void, void>, void, void> const&, boost::multiprecision::detail::bitwise_or const&) C:/msys64/clang64/include/boost/multiprecision/number.hpp:1521:10
    #10 0x7ff60fb579b9 in void boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_op
tion)1>::do_assign<boost::multiprecision::detail::bitwise_or, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multipr
ecision::expression_template_option)1>, boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_ty
pe)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>, void, void>(boost::multiprecision::detail::expression<boost::multiprecision::detail::bitwise_or, boost::multiprecision::number<boost::multiprecision::backends::cpp_
int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boos
t::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, 
void>, void, void> const&, std::__1::integral_constant<bool, true> const&) C:/msys64/clang64/include/boost/multiprecision/number.hpp:1222:7
    #11 0x7ff60fb56cf9 in std::__1::enable_if<std::is_convertible<boost::multiprecision::detail::expression<boost::multiprecision::detail::bitwise_or, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multip
recision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0
ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>, void, void>::result_type, boost::multiprecision::number<boost::multiprecisi
on::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>>::value, boost::multiprecision::number<boost::multiprecision::backends::
cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>&>::type boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend
<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>::operator=<boost::multiprecision::detail::bitwise_or, boost::multiprecision::number<boost::multipreci
sion::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::detail::expression<boost::multiprecision::deta
il::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsign
ed long long, void, void>, void, void>(boost::multiprecision::detail::expression<boost::multiprecision::detail::bitwise_or, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_typ
e)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision
::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>, void, void> const&) C:/msys64/clang64/include/boost/multiprecision/number.hpp:319:7
    #12 0x7ff60fb51c8c in boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)
1> std::__1::accumulate[abi:v15007]<unsigned char const*, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecis
ion::expression_template_option)1>, main::$_0>(unsigned char const*, unsigned char const*, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned
 long long>>, (boost::multiprecision::expression_template_option)1>, main::$_0) C:/msys64/clang64/include/c++/v1/__numeric/accumulate.h:45:16
    #13 0x7ff60fb5164c in main main.cpp:18:14
    #14 0x7ff60fb51315 in __tmainCRTStartup C:/M/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:272:15
    #15 0x7ff60fb51365 in .l_start C:/M/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:193:9
    #16 0x7ff9b7457613  (C:\WINDOWS\System32\KERNEL32.DLL+0x180017613)
    #17 0x7ff9b77026a0  (C:\WINDOWS\SYSTEM32\ntdll.dll+0x1800526a0)

Address 0x00f79ccfed58 is located in stack of thread T0 at offset 24 in frame
    #0 0x7ff60fb58bff in void boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_opt
ion)1>::do_bitwise_or<boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::al
locator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void>, boost::multiprecision::detail::shift_left>(boost::multiprecision::detail::expression<boost::multiprecision::detail::shift_left, boost::multiprecision::number<boost::multiprecision::b
ackends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>, (boost::multiprecision::expression_template_option)1>, unsigned long long, void, void> const&, boost::multiprecision::detail::shift
_left const&) C:/msys64/clang64/include/boost/multiprecision/number.hpp:2113

  This frame has 1 object(s):
    [32, 64) 'temp' (line 2116) <== Memory access at offset 24 underflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp, SEH and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-underflow C:/msys64/clang64/include/boost/multiprecision/cpp_int/bitwise.hpp:334:25 in void boost::multiprecision::backends::left_shift_byte<boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multip
recision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>>(boost::multiprecision::backends::cpp_int_backend<0ull, 0ull, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long>>&, unsigned __int128)
Shadow bytes around the buggy address:
  0x027524f9fd50: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 01 f3 f3 f3
  0x027524f9fd60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x027524f9fd70: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 01 f2 01 f3
  0x027524f9fd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x027524f9fd90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x027524f9fda0: 00 00 00 00 00 00 00 00 f1 f1 f1[f1]00 00 00 00
  0x027524f9fdb0: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
  0x027524f9fdc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x027524f9fdd0: f1 f1 f1 f1 f8 f2 f2 f2 f8 f8 f2 f2 f8 f2 f2 f2
  0x027524f9fde0: 00 00 f2 f2 01 f2 f8 f8 f2 f2 f8 f2 f2 f2 f8 f2
  0x027524f9fdf0: f8 f2 f2 f2 f8 f2 f8 f8 f2 f2 f8 f2 f8 f8 f2 f2
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==8032==ABORTING

Process finished with exit code 1

Solution

  • Expression templates strike again!

    The result of your lambda expression is not BigInt. It is an expression that lazily refers to the operands (much simplified):

    detail::expression<detail::bitwise_or, number<backends::cpp_int_backend<...>, et_on>,
                       detail::expression<detail::shift_left, number<backends::cpp_int_backend<...>, et_on>,
                                          unsigned long, void, void>,
                       void, void>;
    

    Fixing that removes the problem:

    BigInt result = acc | (byte << shift); // look, no auto!
    

    Or

    std::accumulate(b.cbegin(), b.cend(), initial,
            [&shift](BigInt const& acc, uint8_t it)
    -> BigInt { // trailing return
    

    Alternative Solution

    The more general solution is to disable expression templates for your BigInt altogether:

    //using BigInt = boost::multiprecision::cpp_int;
    using BigInt =
        boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>, boost::multiprecision::et_off>;