Boost logo

Boost :

Subject: Re: [boost] [gil] gcc fail with simple code
From: Stefan Seefeld (stefan_at_[hidden])
Date: 2018-03-28 19:10:34


On 28.03.2018 14:48, Christian Henning via Boost wrote:
> Thank you Andrey!
>
> With -ftrapv the code crashes at this point:
>> #0 __GI_raise (sig=sig_at_entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
>> #1 0x00007ffff7490f5d in __GI_abort () at abort.c:90
>> #2 0x00007ffff783b2d8 in __addvsi3 () from /lib/x86_64-linux-gnu/libgcc_s
>> .so.1
>> #3 0x00005555555548a9 in boost::gil::detail::channel_co
>> nvert_to_unsigned<int>::operator() (this=<optimized out>, x=<optimized
>> out>) at ./boost/gil/channel_algorithm.hpp:332
>> #4 boost::gil::channel_converter<int, int>::operator() (this=<optimized
>> out>, src=@0x555555755014: 2147483647) at ./boost/gil/channel_algorithm.
>> hpp:368
>> #5 boost::gil::channel_convert<int, int> (src=@0x555555755014: 2147483647)
>> at ./boost/gil/channel_algorithm.hpp:377
>> #6 main (argc=<optimized out>, argv=<optimized out>) at test_gil.cpp:32
>>
>> channel_algorithm.hpp:332 is this line:
>>
>> type operator()(bits32s x) const { return
>> static_cast<bits32>(x+(1<<31)); }
>>
>> This shift is UB because it overflows (until C++17, I think?). The
>> addition will also overflow unless x is 0.
>>
>> I would suggest casting to unsigned first and then performing the math.
>
>
> I assume this is what you meant:
>
> template <> struct channel_convert_to_unsigned<bits32s> : public
> std::unary_function<bits32s,bits32> {
> typedef bits32 type;
> type operator()(bits32s x) const
> {
> uint32_t a = static_cast<uint32_t>(x);
> a += (1 << 31);
>
> return static_cast<bits32>(a);
> }
> };

Or simply replace `static_cast<bits32>(x+(1<<31))` by
`static_cast<bits32>(x)+(1<<31)` (i.e., cast `x` rather than the full
expression).

Stefan

-- 
      ...ich hab' noch einen Koffer in Berlin...
    

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk