From 9cc80b51cf98c13a140b00effb38329e7210d03c Mon Sep 17 00:00:00 2001
From: Matthew Craven <5086-clyring@users.noreply.gitlab.haskell.org>
Date: Thu, 4 May 2023 14:06:53 +0000
Subject: [PATCH] Round up unboxed Bool arrays to whole-word sizes

---
 Data/Array/Base.hs | 11 +++++++++--
 changelog.md       |  5 +++++
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/Data/Array/Base.hs b/Data/Array/Base.hs
index 3d271efb..4b744ea9 100644
--- a/Data/Array/Base.hs
+++ b/Data/Array/Base.hs
@@ -1360,8 +1360,15 @@ instance MArray (STUArray s) Word64 (ST s) where
 
 bOOL_SCALE, wORD_SCALE, dOUBLE_SCALE, fLOAT_SCALE :: Int# -> Int#
 bOOL_SCALE n# =
-    -- + 7 to handle case where n is not divisible by 8
-    (n# +# 7#) `uncheckedIShiftRA#` 3#
+    -- Round the number of bits up to the next whole-word-aligned number
+    -- of bytes to avoid ghc#23132; the addition can signed-overflow but
+    -- that's OK because it will not unsigned-overflow and the logical
+    -- right-shift brings us back in-bounds
+#if SIZEOF_HSWORD == 4
+    ((n# +# 31#) `uncheckedIShiftRL#` 5#) `uncheckedIShiftL#` 2#
+#elif SIZEOF_HSWORD == 8
+    ((n# +# 63#) `uncheckedIShiftRL#` 6#) `uncheckedIShiftL#` 3#
+#endif
 wORD_SCALE   n# = safe_scale scale# n# where !(I# scale#) = SIZEOF_HSWORD
 dOUBLE_SCALE n# = safe_scale scale# n# where !(I# scale#) = SIZEOF_HSDOUBLE
 fLOAT_SCALE  n# = safe_scale scale# n# where !(I# scale#) = SIZEOF_HSFLOAT
diff --git a/changelog.md b/changelog.md
index 852c0e8a..341174cf 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,10 @@
 # Changelog for [`array` package](http://hackage.haskell.org/package/array)
 
+## NEXT  *TBA*
+
+  * Unboxed Bool arrays no longer cause spurious alarms
+    when used with `-fcheck-prim-bounds`
+
 ## 0.5.5.0  *February 2022*
 
   * Compatibility with GHC's new JavaScript backend.
-- 
GitLab