summaryrefslogtreecommitdiff
path: root/libraries/base/Data/Bits.hs
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/base/Data/Bits.hs')
-rw-r--r--libraries/base/Data/Bits.hs22
1 files changed, 16 insertions, 6 deletions
diff --git a/libraries/base/Data/Bits.hs b/libraries/base/Data/Bits.hs
index 4226f8e967..000e663b83 100644
--- a/libraries/base/Data/Bits.hs
+++ b/libraries/base/Data/Bits.hs
@@ -205,7 +205,8 @@ class Eq a => Bits a where
x `complementBit` i = x `xor` bit i
{-| Shift the argument left by the specified number of bits
- (which must be non-negative).
+ (which must be non-negative). Some instances may throw an
+ 'Control.Exception.Overflow' exception if given a negative input.
An instance can define either this and 'shiftR' or the unified
'shift', depending on which is more convenient for the type in
@@ -227,7 +228,8 @@ class Eq a => Bits a where
{-| Shift the first argument right by the specified number of bits. The
result is undefined for negative shift amounts and shift amounts
- greater or equal to the 'bitSize'.
+ greater or equal to the 'bitSize'. Some instances may throw an
+ 'Control.Exception.Overflow' exception if given a negative input.
Right shifts perform sign extension on signed number types;
i.e. they fill the top bits with 1 if the @x@ is negative
@@ -450,9 +452,13 @@ instance Bits Int where
(I# x#) `shift` (I# i#)
| isTrue# (i# >=# 0#) = I# (x# `iShiftL#` i#)
| otherwise = I# (x# `iShiftRA#` negateInt# i#)
- (I# x#) `shiftL` (I# i#) = I# (x# `iShiftL#` i#)
+ (I# x#) `shiftL` (I# i#)
+ | isTrue# (i# >=# 0#) = I# (x# `iShiftL#` i#)
+ | otherwise = overflowError
(I# x#) `unsafeShiftL` (I# i#) = I# (x# `uncheckedIShiftL#` i#)
- (I# x#) `shiftR` (I# i#) = I# (x# `iShiftRA#` i#)
+ (I# x#) `shiftR` (I# i#)
+ | isTrue# (i# >=# 0#) = I# (x# `iShiftRA#` i#)
+ | otherwise = overflowError
(I# x#) `unsafeShiftR` (I# i#) = I# (x# `uncheckedIShiftRA#` i#)
{-# INLINE rotate #-} -- See Note [Constant folding for rotate]
@@ -488,9 +494,13 @@ instance Bits Word where
(W# x#) `shift` (I# i#)
| isTrue# (i# >=# 0#) = W# (x# `shiftL#` i#)
| otherwise = W# (x# `shiftRL#` negateInt# i#)
- (W# x#) `shiftL` (I# i#) = W# (x# `shiftL#` i#)
+ (W# x#) `shiftL` (I# i#)
+ | isTrue# (i# >=# 0#) = W# (x# `shiftL#` i#)
+ | otherwise = overflowError
(W# x#) `unsafeShiftL` (I# i#) = W# (x# `uncheckedShiftL#` i#)
- (W# x#) `shiftR` (I# i#) = W# (x# `shiftRL#` i#)
+ (W# x#) `shiftR` (I# i#)
+ | isTrue# (i# >=# 0#) = W# (x# `shiftRL#` i#)
+ | otherwise = overflowError
(W# x#) `unsafeShiftR` (I# i#) = W# (x# `uncheckedShiftRL#` i#)
(W# x#) `rotate` (I# i#)
| isTrue# (i'# ==# 0#) = W# x#