mirror of
https://github.com/apple/swift.git
synced 2026-10-04 11:58:22 +02:00
A C function returning a foreign reference or CoreFoundation type unretained cannot be safely implemented, because there is no way to ensure that the result object lives past the return. However, such C functions do exist, and we would like to be able to implement them via `@c @implementation`. Extend the signature-matching logic for `@implementation` to permit an `Unmanaged<T>` result even when the signature comes in an `T` to allow the use of `@implementation` here. Implements rdar://188429740
78 lines
2.7 KiB
Swift
78 lines
2.7 KiB
Swift
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen -import-objc-header %S/Inputs/c_implementation.h -swift-version 6 %s -target %target-stable-abi-triple > %t
|
|
// RUN: %FileCheck --input-file %t %s
|
|
|
|
// REQUIRES: objc_interop
|
|
|
|
import Foundation
|
|
|
|
@_silgen_name("getString")
|
|
func getString() -> String
|
|
|
|
@c @implementation
|
|
func returns_retained() -> CFString? {
|
|
return getString() as CFString
|
|
}
|
|
|
|
// CHECK-LABEL: sil{{.*}} @$s16c_implementation16returns_retainedSo11CFStringRefaSgyFTo : $@convention(c) () -> @owned Optional<CFString> {
|
|
|
|
@c @implementation
|
|
func returns_not_retained() -> CFString? {
|
|
return getString() as CFString
|
|
}
|
|
|
|
// CHECK-LABEL: sil{{.*}} @$s16c_implementation20returns_not_retainedSo11CFStringRefaSgyFTo : $@convention(c) () -> @autoreleased Optional<CFString> {
|
|
|
|
@c @implementation
|
|
func passes_borrowed(_ string: CFString?) {
|
|
|
|
}
|
|
|
|
// CHECK-LABEL: sil{{.*}} @$s16c_implementation15passes_borrowedyySo11CFStringRefaSgFTo : $@convention(c) (Optional<CFString>) -> () {
|
|
|
|
@c @implementation
|
|
func passes_consumed(_ string: consuming CFString?) {
|
|
|
|
}
|
|
|
|
// CHECK-LABEL: sil{{.*}} @$s16c_implementation15passes_consumedyySo11CFStringRefaSgnFTo : $@convention(c) (@owned Optional<CFString>) -> () {
|
|
|
|
@c @implementation
|
|
func returns_unaudited() -> Unmanaged<CFString>? {
|
|
return Unmanaged.passRetained(getString() as CFString)
|
|
}
|
|
|
|
// CHECK-LABEL: sil{{.*}} @$s16c_implementation17returns_unauditeds9UnmanagedVySo11CFStringRefaGSgyFTo : $@convention(c) () -> Optional<Unmanaged<CFString>> {
|
|
|
|
// A 'CFTypeRef' is lowered as 'AnyObject' and picks up the ownership
|
|
// convention of the C declaration, so it participates in the same reference
|
|
// counting that 'AnyObject' uses.
|
|
|
|
@c @implementation
|
|
func passes_any_borrowed(_ obj: CFTypeRef?) {
|
|
|
|
}
|
|
|
|
// CHECK-LABEL: sil{{.*}} @$s16c_implementation19passes_any_borrowedyyyXlSgFTo : $@convention(c) (Optional<AnyObject>) -> () {
|
|
|
|
@c @implementation
|
|
func returns_any_retained() -> CFTypeRef? {
|
|
return getString() as CFString
|
|
}
|
|
|
|
// CHECK-LABEL: sil{{.*}} @$s16c_implementation20returns_any_retainedyXlSgyFTo : $@convention(c) () -> @owned Optional<AnyObject> {
|
|
|
|
|
|
@c @implementation
|
|
func returns_not_retained_unmanaged() -> Unmanaged<CFString>? {
|
|
return nil
|
|
}
|
|
|
|
// CHECK-LABEL: sil{{.*}} @$s16c_implementation30returns_not_retained_unmanageds9UnmanagedVySo11CFStringRefaGSgyFTo : $@convention(c) () -> Optional<Unmanaged<CFString>> {
|
|
|
|
@c @implementation
|
|
func returns_retained_unmanaged() -> Unmanaged<CFString>? {
|
|
return Unmanaged.passRetained(getString() as CFString)
|
|
}
|
|
|
|
// CHECK-LABEL: sil{{.*}} @$s16c_implementation26returns_retained_unmanageds9UnmanagedVySo11CFStringRefaGSgyFTo : $@convention(c) () -> Optional<Unmanaged<CFString>> {
|