Fix the right-shift operation for negative big integers (fixes #12136)
authorDaishi Nakajima <nakaji.dayo@gmail.com>
Thu, 26 Jan 2017 23:14:08 +0000 (18:14 -0500)
committerBen Gamari <ben@smart-cactus.org>
Thu, 26 Jan 2017 23:14:09 +0000 (18:14 -0500)
commit06b9561a2f10de68cc14b68a9bfa7617c0019bd9
tree1ebb18fa1a6e417fda86ce45005c155dfb57a610
parent2ffcdfadaa53c9bc4b24606dc2e28a356a60d21e
Fix the right-shift operation for negative big integers (fixes #12136)

In `x shiftR y`, any of the following conditions cause an abort:
- `x` is a negative big integer
- The size of `x` and `y` is a multiple of `GMP_NUMB_BITS`
- The bit of the absolute value of `x` is filled with `1`

For example:
Assuming `GMP_NUMB_BITS = 2`,  the processing of `-15 shiftR 2` is as
follows:

1. -15 = -1111 (twos complement: 10001)
2. right shift 2 (as a positive number) -> 0011
3. Due to the shift larger than GMP_NUMB_BITS, the size of the
destination is decreasing (2bit) -> 11
4. Add 1, and get carry: (1) 00
5. abort

I fixed it that the destination size does not decrease in such a case.

Test Plan: I tested the specific case being reported.

Reviewers: goldfire, austin, hvr, bgamari, rwbarton

Reviewed By: bgamari, rwbarton

Subscribers: mpickering, rwbarton, thomie

Differential Revision: https://phabricator.haskell.org/D2998

GHC Trac Issues: #12136
libraries/integer-gmp/cbits/wrappers.c
libraries/integer-gmp/src/GHC/Integer/Type.hs
testsuite/tests/numeric/should_run/T12136.hs [new file with mode: 0644]
testsuite/tests/numeric/should_run/T12136.stdout [new file with mode: 0644]
testsuite/tests/numeric/should_run/all.T