summaryrefslogtreecommitdiff
path: root/compiler/prelude/PrelRules.hs
diff options
context:
space:
mode:
authorAlec Theriault <alec.theriault@gmail.com>2019-01-10 23:44:04 -0800
committerBen Gamari <ben@smart-cactus.org>2019-02-20 14:28:54 -0500
commit0d917dbb46f91151314a2d50573d5acd4b70213f (patch)
tree2d55d56b9f7560a3b1eaa75e7678d547bb657685 /compiler/prelude/PrelRules.hs
parentc1ac8477e79a5ab8fcf554c81d5fae0ab9dc1fd3 (diff)
downloadhaskell-0d917dbb46f91151314a2d50573d5acd4b70213f.tar.gz
Error out of invalid Int/Word bit shifts
Although the Haddock's for `shiftL` and `shiftR` do require the number of bits to be non-negative, we should still check this before calling out to primitives (which also have undefined behaviour for negative bit shifts). If a user _really_ wants to bypass checks that the number of bits is sensible, they already have the aptly-named `unsafeShiftL`/`unsafeShiftR` at their disposal. See #16111.
Diffstat (limited to 'compiler/prelude/PrelRules.hs')
-rw-r--r--compiler/prelude/PrelRules.hs5
1 files changed, 2 insertions, 3 deletions
diff --git a/compiler/prelude/PrelRules.hs b/compiler/prelude/PrelRules.hs
index f8b8f91bcc..7111c7b07a 100644
--- a/compiler/prelude/PrelRules.hs
+++ b/compiler/prelude/PrelRules.hs
@@ -474,12 +474,11 @@ shiftRule shift_op
; case e1 of
_ | shift_len == 0
-> return e1
- | shift_len < 0 || wordSizeInBits dflags < shift_len
- -> return (mkRuntimeErrorApp rUNTIME_ERROR_ID wordPrimTy
- ("Bad shift length" ++ show shift_len))
-- Do the shift at type Integer, but shift length is Int
Lit (LitNumber nt x t)
+ | 0 < shift_len
+ , shift_len <= wordSizeInBits dflags
-> let op = shift_op dflags
y = x `op` fromInteger shift_len
in liftMaybe $ Just (Lit (mkLitNumberWrap dflags nt y t))