Commit be63d299 authored by Simon Jakobi's avatar Simon Jakobi Committed by Marge Bot

Fix isValidNatural: The BigNat in NatJ# must have at least 2 limbs

Previously the `integer-gmp` variant of `isValidNatural` would fail to
detect values `<= maxBound::Word` that were incorrectly encoded using
the `NatJ#` constructor.
parent 9bb58799
Pipeline #6562 passed with stages
in 561 minutes and 16 seconds
......@@ -157,7 +157,9 @@ data Natural = NatS# GmpLimb# -- ^ in @[0, maxBound::Word]@
isValidNatural :: Natural -> Bool
isValidNatural (NatS# _) = True
isValidNatural (NatJ# bn) = isTrue# (isValidBigNat# bn)
&& isTrue# (sizeofBigNat# bn ># 0#)
-- A 1-limb BigNat could fit into a NatS#, so we
-- require at least 2 limbs.
&& isTrue# (sizeofBigNat# bn ># 1#)
signumNatural :: Natural -> Natural
signumNatural (NatS# 0##) = NatS# 0##
......
......@@ -5,6 +5,10 @@
* Add a `TestEquality` instance for the `Compose` newtype.
* Fix the `integer-gmp` variant of `isValidNatural`: Previously it would fail
to detect values `<= maxBound::Word` that were incorrectly encoded using
the `NatJ#` constructor.
## 4.13.0.0 *TBA*
* Bundled with GHC *TBA*
......
......@@ -40,6 +40,7 @@ test('take001', extra_run_opts('1'), compile_and_run, [''])
test('inits', normal, compile_and_run, [''])
test('genericNegative001', extra_run_opts('-1'), compile_and_run, [''])
test('ix001', normal, compile_and_run, [''])
test('isValidNatural', reqlib('integer-gmp'), compile_and_run, [''])
# need to add -K64m to the compiler opts, so that GHCi gets it too
test('ioref001',
......
{-# language MagicHash #-}
import GHC.Integer.GMP.Internals
import GHC.Natural
main = print $ map isValidNatural [0, 1, maxWord, maxWord + 1, invalid]
where
maxWord = fromIntegral (maxBound :: Word)
invalid = NatJ# oneBigNat -- 1 would fit into the NatS# constructor.
......@@ -1778,6 +1778,8 @@ foreign import ccall unsafe "gmp.h __gmpn_popcount"
-- BigNat-wrapped ByteArray#-primops
-- | Return number of limbs contained in 'BigNat'.
--
-- The result is always @>= 1@ since even zero is encoded with 1 limb.
sizeofBigNat# :: BigNat -> GmpSize#
sizeofBigNat# (BN# x#)
= sizeofByteArray# x# `uncheckedIShiftRL#` GMP_LIMB_SHIFT#
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment