Files
swift-mirror/test/SILGen/c_implementation.swift
Doug Gregor f2340ec9af [C interop] Allow an Unmanaged<T> result in a @c @implementation function
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
2026-09-29 07:49:36 -07:00

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>> {