From 101c7cbbdbe86a20043787609b11584abc4d46ce Mon Sep 17 00:00:00 2001 From: Mike Ash Date: Tue, 9 Oct 2018 12:48:44 -0400 Subject: [PATCH] [Runtime] Fix a leak when reading a weak property with Mirror. SR-8878 rdar://problem/44872927 --- stdlib/public/runtime/ReflectionMirror.mm | 1 + test/stdlib/WeakMirror.swift | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/stdlib/public/runtime/ReflectionMirror.mm b/stdlib/public/runtime/ReflectionMirror.mm index eae59f80fec5e..d4e248460fa2d 100644 --- a/stdlib/public/runtime/ReflectionMirror.mm +++ b/stdlib/public/runtime/ReflectionMirror.mm @@ -172,6 +172,7 @@ static bool loadSpecialReferenceStorage(OpaqueValue *fieldData, reinterpret_cast(temporaryValue)); type->deallocateBufferIn(&temporaryBuffer); + swift_unknownObjectRelease(strongValue); return true; } diff --git a/test/stdlib/WeakMirror.swift b/test/stdlib/WeakMirror.swift index e4e55264acdc7..eb6e8aead355e 100644 --- a/test/stdlib/WeakMirror.swift +++ b/test/stdlib/WeakMirror.swift @@ -99,6 +99,24 @@ mirrors.test("struct/StructHasNativeWeakReference") { print(extractedChild) } +// SR-8878: Using Mirror to access a weak reference results in object +// being retained indefinitely +mirrors.test("class/NativeSwiftClassHasNativeWeakReferenceNoLeak") { + weak var verifier: AnyObject? + do { + let parent = NativeSwiftClassHasWeak(x: 1010) + let child = NativeSwiftClass(x: 2020) + verifier = child + parent.weakProperty = child + let mirror = Mirror(reflecting: parent) + let children = Array(mirror.children) + let extractedChild = children[0].1 as! NativeSwiftClass + expectNotNil(extractedChild) + expectNotNil(verifier) + } + expectNil(verifier) +} + #if _runtime(_ObjC) import Foundation