Merge pull request #83775 from glessard/rdar158440246-62

[stdlib, 6.2.x] guard against deinitializing empty OutputSpan instances
This commit is contained in:
Guillaume Lessard
2025-08-22 13:42:00 -07:00
committed by GitHub
2 changed files with 18 additions and 1 deletions

View File

@@ -315,6 +315,7 @@ extension OutputSpan where Element: ~Copyable {
@_alwaysEmitIntoClient
@lifetime(self: copy self)
public mutating func removeAll() {
guard count > 0 else { return }
_ = unsafe _start().withMemoryRebound(to: Element.self, capacity: _count) {
unsafe $0.deinitialize(count: _count)
}

View File

@@ -35,7 +35,9 @@ struct Allocation<T>: ~Copyable {
_ body: (inout OutputSpan<T>) throws(E) -> Void
) throws(E) {
if count != nil { fatalError() }
var outputBuffer = OutputSpan<T>(buffer: allocation, initializedCount: 0)
var allocation = allocation
if allocation.count == 0 { allocation = .init(start: nil, count: 0) }
var outputBuffer = OutputSpan(buffer: allocation, initializedCount: 0)
do {
try body(&outputBuffer)
let initialized = outputBuffer.finalize(for: allocation)
@@ -188,6 +190,20 @@ suite.test("deinitialize buffer")
catch {
expectTrue(false)
}
a = Allocation(of: 0, Int.self)
do {
try a.initialize {
expectEqual($0.freeCapacity, 0)
throw MyTestError.error
}
}
catch MyTestError.error {
expectEqual(a.isEmpty, true)
}
catch {
expectTrue(false)
}
}
suite.test("InlineArray initialization")