SIGABRT on right-shift operation against long negative integer
When the code like bellow is executed, the shiftR call causes SIGABRT.
c128.hs
import Data.Bits
x:: Integer
x = 1 - (1 `shiftL` (128 + 64))
main :: IO ()
main = print $ x `shiftR` 128
I make this report using examples in GHC 7.10.3, and I found the same problem in GHC 8.0.1 too.
backtrace using GDB
% ghc -O0 c128.hs
[1 of 1] Compiling Main ( c128.hs, c128.o )
Linking c128 ...
% gdb ./c128
GNU gdb (Debian 7.10-1+b1) 7.10
...
Reading symbols from ./c128...(no debugging symbols found)...done.
(gdb) run
Starting program: /home/hibi/src/haskell/crash/Haskell/c128
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGABRT, Aborted.
0x00007ffff6ed4478 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55
55 ../sysdeps/unix/sysv/linux/raise.c: そのようなファイルやディレクトリはありません.
(gdb) bt
#0 0x00007ffff6ed4478 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55
#1 0x00007ffff6ed58fa in __GI_abort () at abort.c:89
#2 0x00000000004716df in integer_gmp_mpn_rshift_2c ()
#3 0x000000000046e004 in salz_info ()
#4 0x0000000000000000 in ?? ()
(gdb) frame 2
#2 0x00000000004716df in integer_gmp_mpn_rshift_2c ()
(gdb) disas
Dump of assembler code for function integer_gmp_mpn_rshift_2c:
0x0000000000471630 <+0>: push %r13
...
0x00000000004716d8 <+168>: jne 0x4716c0 <integer_gmp_mpn_rshift_2c+144>
0x00000000004716da <+170>: callq 0x402c80 <abort@plt>
=> 0x00000000004716df <+175>: nop
0x00000000004716e0 <+176>: lea 0x0(,%rdx,8),%rdx
...
End of assembler dump.
(gdb)
I found abort call in integer_gmp_mpn_rshift_2c.
ghc-7.10.3/libraries/integer-gmp2/cbits/wrappers.c
mp_limb_t
integer_gmp_mpn_rshift_2c (mp_limb_t rp[], const mp_limb_t sp[],
const mp_size_t sn, const mp_bitcnt_t count)
{
...
// round if non-zero bits were shifted out
if (nz_shift_out)
if (mpn_add_1(rp, rp, rn, 1))
abort(); /* should never happen */
return rp[rn-1];
}