diff --git a/stdlib/public/runtime/HeapObject.cpp b/stdlib/public/runtime/HeapObject.cpp index c9a311ca62bf9..f5b6f029d9db2 100644 --- a/stdlib/public/runtime/HeapObject.cpp +++ b/stdlib/public/runtime/HeapObject.cpp @@ -292,6 +292,26 @@ void SWIFT_RT_ENTRY_IMPL(swift_nonatomic_retain_n)(HeapObject *object, uint32_t object->refCounts.incrementNonAtomic(n); } +#if !SWIFT_OBJC_INTEROP + +// For CF functions with 'Get' semantics, the compiler currently assumes that +// the result is autoreleased and must be retained. It does so on all platforms +// by emitting a call to objc_retainAutoreleasedReturnValue. On Darwin, this is +// implemented by the ObjC runtime. On Linux, there is no runtime, and therefore +// we have to stub it out here ourselves. The compiler will eventually call +// swift_release to balance the retain below. This is a workaround until the +// compiler no longer emits this callout on Linux. +SWIFT_RT_ENTRY_VISIBILITY +extern "C" +void *objc_retainAutoreleasedReturnValue(HeapObject *obj) { + if (obj) { + swift::swift_retain(obj); + return obj; + } + else return NULL; +} +#endif + void swift::swift_release(HeapObject *object) SWIFT_CC(RegisterPreservingCC_IMPL) { SWIFT_RT_ENTRY_REF(swift_release)(object);