summaryrefslogtreecommitdiff
path: root/compiler/utils/FastString.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/utils/FastString.hs')
-rw-r--r--compiler/utils/FastString.hs20
1 files changed, 13 insertions, 7 deletions
diff --git a/compiler/utils/FastString.hs b/compiler/utils/FastString.hs
index f11c4ebbb8..9a74eff16d 100644
--- a/compiler/utils/FastString.hs
+++ b/compiler/utils/FastString.hs
@@ -531,16 +531,22 @@ cmpStringPrefix ptr1 ptr2 len =
do r <- memcmp ptr1 ptr2 len
return (r == 0)
-
hashStr :: Ptr Word8 -> Int -> Int
-- use the Addr to produce a hash value between 0 & m (inclusive)
hashStr (Ptr a#) (I# len#) = loop 0# 0#
- where
- loop h n | isTrue# (n ==# len#) = I# h
- | otherwise = loop h2 (n +# 1#)
- where
- !c = ord# (indexCharOffAddr# a# n)
- !h2 = (h *# 16777619#) `xorI#` c
+ where
+ loop h n =
+ if isTrue# (n ==# len#) then
+ I# h
+ else
+ let
+ -- DO NOT move this let binding! indexCharOffAddr# reads from the
+ -- pointer so we need to evaluate this based on the length check
+ -- above. Not doing this right caused #17909.
+ !c = ord# (indexCharOffAddr# a# n)
+ !h2 = (h *# 16777619#) `xorI#` c
+ in
+ loop h2 (n +# 1#)
-- -----------------------------------------------------------------------------
-- Operations