diff options
author | Ben Gamari <ben@smart-cactus.org> | 2022-08-05 23:56:13 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2022-08-08 19:39:57 -0400 |
commit | 50912d689b6c405f979fd786cf2858d04552fc29 (patch) | |
tree | 489925fa62e442d6516f5df6a53afbba1103d0f2 /rts | |
parent | ae707762335dabe2bb7e40639fd2ab2c7d3234fd (diff) | |
download | haskell-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.
Diffstat (limited to 'rts')
-rw-r--r-- | rts/PrimOps.cmm | 5 | ||||
-rw-r--r-- | rts/include/Cmm.h | 3 |
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); \ |