Skip to content

Commit feb97aa

Browse files
authored
[Runtime] Fix leak of bridge objects in swift_generic_initWithTake (#69978)
rdar://118606044 The initWithTakeTable accidentally referenced bridgeRetain instead of copyingInitWithTake, which caused a leak when an object containing a bridge reference was also not bitwise takable.
1 parent b4b2e3f commit feb97aa

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

stdlib/public/runtime/BytecodeLayouts.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1102,7 +1102,7 @@ static const InitFn initWithTakeTable[] = {
11021102
nullptr,
11031103
nullptr,
11041104
&unknownWeakInitWithTake,
1105-
&bridgeRetainBranchless,
1105+
nullptr,
11061106
nullptr,
11071107
nullptr,
11081108
nullptr, // Custom

test/Interpreter/Inputs/layout_string_witnesses_types.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,16 @@ public struct SinglePayloadEnumExtraTagBytesWrapper {
401401
}
402402
}
403403

404+
public struct NotBitwiseTakableBridge<T> {
405+
let x: Int = 0
406+
let y: [T]
407+
weak var z: AnyObject? = nil
408+
409+
public init(_ y: [T]) {
410+
self.y = y
411+
}
412+
}
413+
404414
public enum SinglePayloadEnumExtraTagBytes {
405415
case empty0
406416
case empty1
@@ -592,6 +602,11 @@ public func testInit<T>(_ ptr: UnsafeMutablePointer<T>, to x: T) {
592602
ptr.initialize(to: x)
593603
}
594604

605+
@inline(never)
606+
public func testInitTake<T>(_ ptr: UnsafeMutablePointer<T>, to x: consuming T) {
607+
ptr.initialize(to: consume x)
608+
}
609+
595610
@inline(never)
596611
public func testDestroy<T>(_ ptr: UnsafeMutablePointer<T>) {
597612
ptr.deinitialize(count: 1)

test/Interpreter/layout_string_witnesses_static.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,50 @@ func testEnumWithExistential() {
807807

808808
testEnumWithExistential()
809809

810+
// Regression test for rdar://118606044
811+
func testNotBitwiseTakableBridge() {
812+
let ptr = UnsafeMutablePointer<NotBitwiseTakableBridge<SimpleClass>>.allocate(capacity: 1)
813+
814+
// initWithTake
815+
do {
816+
let x = NotBitwiseTakableBridge([SimpleClass(x: 23)])
817+
testInitTake(ptr, to: consume x)
818+
}
819+
820+
// assignWithTake
821+
do {
822+
let y = NotBitwiseTakableBridge([SimpleClass(x: 33)])
823+
824+
// CHECK-NEXT: Before deinit
825+
print("Before deinit")
826+
827+
// CHECK-NEXT: SimpleClass deinitialized!
828+
testAssign(ptr, from: y)
829+
}
830+
831+
// assignWithCopy
832+
do {
833+
var z = NotBitwiseTakableBridge([SimpleClass(x: 43)])
834+
835+
// CHECK-NEXT: Before deinit
836+
print("Before deinit")
837+
838+
// CHECK-NEXT: SimpleClass deinitialized!
839+
testAssignCopy(ptr, from: &z)
840+
}
841+
842+
// CHECK-NEXT: Before deinit
843+
print("Before deinit")
844+
845+
// destroy
846+
// CHECK-NEXT: SimpleClass deinitialized!
847+
testDestroy(ptr)
848+
849+
ptr.deallocate()
850+
}
851+
852+
testNotBitwiseTakableBridge()
853+
810854
#if os(macOS)
811855
func testObjc() {
812856
let ptr = UnsafeMutablePointer<ObjcWrapper>.allocate(capacity: 1)

0 commit comments

Comments
 (0)