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