Boost logo

Boost :

Subject: Re: [boost] [gil] gcc fail with simple code
From: Christian Henning (chhenning_at_[hidden])
Date: 2018-03-28 18:48:50


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);
    }
};


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