summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-08-05 23:56:13 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-08-08 19:39:57 -0400
commit50912d689b6c405f979fd786cf2858d04552fc29 (patch)
tree489925fa62e442d6516f5df6a53afbba1103d0f2
parentae707762335dabe2bb7e40639fd2ab2c7d3234fd (diff)
downloadhaskell-50912d689b6c405f979fd786cf2858d04552fc29.tar.gz
rts: Ensure that Array# card arrays are initialized
In #19143 I noticed that newArray# failed to initialize the card table of newly-allocated arrays. However, embarrassingly, I then only fixed the issue in newArrayArray# and, in so doing, introduced the potential for an integer underflow on zero-length arrays (#21962). Here I fix the issue in newArray#, this time ensuring that we do not underflow in pathological cases. Fixes #19143.
-rw-r--r--rts/PrimOps.cmm5
-rw-r--r--rts/include/Cmm.h3
2 files changed, 7 insertions, 1 deletions
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm
index 9de149ba5f..7bf403086d 100644
--- a/rts/PrimOps.cmm
+++ b/rts/PrimOps.cmm
@@ -350,6 +350,11 @@ stg_newArrayzh ( W_ n /* words */, gcptr init )
StgMutArrPtrs_ptrs(arr) = n;
StgMutArrPtrs_size(arr) = size;
+ /* Ensure that the card array is initialized */
+ if (n != 0) {
+ setCardsValue(arr, 0, n, 0);
+ }
+
// Initialise all elements of the array with the value in R2
p = arr + SIZEOF_StgMutArrPtrs;
for:
diff --git a/rts/include/Cmm.h b/rts/include/Cmm.h
index 0bdb704035..1470b2e0e2 100644
--- a/rts/include/Cmm.h
+++ b/rts/include/Cmm.h
@@ -870,10 +870,11 @@
/*
* Set the cards in the array pointed to by arr for an
* update to n elements, starting at element dst_off to value (0 to indicate
- * clean, 1 to indicate dirty).
+ * clean, 1 to indicate dirty). n must be non-zero.
*/
#define setCardsValue(arr, dst_off, n, value) \
W_ __start_card, __end_card, __cards, __dst_cards_p; \
+ ASSERT(n != 0); \
__dst_cards_p = (arr) + SIZEOF_StgMutArrPtrs + WDS(StgMutArrPtrs_ptrs(arr)); \
__start_card = mutArrPtrCardDown(dst_off); \
__end_card = mutArrPtrCardDown((dst_off) + (n) - 1); \