Skip to content

Commit 0885b4c

Browse files
[stdlib] Fix array slice self-assignment bug (#10958) (#11022)
Fix bug where assigning from self wasn't checking bounds of the assigned slice matched
1 parent df2c112 commit 0885b4c

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

stdlib/public/core/Arrays.swift.gyb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,10 @@ public struct ${Self}<Element>
742742
set(rhs) {
743743
_checkIndex(bounds.lowerBound)
744744
_checkIndex(bounds.upperBound)
745-
if self[bounds]._buffer.identity != rhs._buffer.identity {
745+
// If the replacement buffer has same identity, and the ranges match,
746+
// then this was a pinned in-place modification, nothing further needed.
747+
if self[bounds]._buffer.identity != rhs._buffer.identity
748+
|| bounds != rhs.startIndex..<rhs.endIndex {
746749
self.replaceSubrange(bounds, with: rhs)
747750
}
748751
}

test/stdlib/Inputs/CommonArrayTests.gyb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,23 @@ ${Suite}.test(
373373
// Special cases and one-off tests.
374374
//===----------------------------------------------------------------------===//
375375

376+
${Suite}.test(
377+
"${ArrayType}/subscriptSelfAssignDifferentRanges") {
378+
var arr: ${ArrayType}<Int> = [ 1010, 1020, 1030 ]
379+
arr[0..<0] = arr[...]
380+
expectEqual([ 1010, 1020, 1030, 1010, 1020, 1030 ], arr)
381+
arr[1..<1] = arr[1..<2]
382+
expectEqual([ 1010, 1020, 1020, 1030, 1010, 1020, 1030 ], arr)
383+
arr[1..<1] = arr[1..<2]
384+
expectEqual([ 1010, 1020, 1020, 1020, 1030, 1010, 1020, 1030 ], arr)
385+
arr[1..<2] = arr[0..<1]
386+
expectEqual([ 1010, 1010, 1020, 1020, 1030, 1010, 1020, 1030 ], arr)
387+
arr[0..<5] = arr.dropFirst(5)
388+
expectEqual([ 1010, 1020, 1030, 1010, 1020, 1030 ], arr)
389+
arr[...] = arr[0..<0]
390+
expectEqual([ ], arr)
391+
}
392+
376393
${Suite}.test("${ArrayType}<Void>/map") {
377394
// This code used to crash because it generated an array of Void with
378395
// stride == 0.

0 commit comments

Comments
 (0)