Skip to content

Commit 79b59f1

Browse files
committed
Lower imported C structs and unions as addressable-for-dependencies.
C code is highly likely to want to use pointers as references between dependent structs, and we would like to be able to readily map these to lifetime-dependent Swift values. Making C types addressable-for-dependencies ensures that any function producing a dependency on such a value receives a stable in-memory address for that value, allowing borrows and inout accesses to always be representable as pointers. rdar://153648393
1 parent d03fd67 commit 79b59f1

File tree

4 files changed

+28
-5
lines changed

4 files changed

+28
-5
lines changed

lib/SIL/IR/TypeLowering.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2537,6 +2537,11 @@ namespace {
25372537
// that a union contains a pointer.
25382538
if (recordDecl->isOrContainsUnion())
25392539
properties.setIsOrContainsRawPointer();
2540+
2541+
// Treat imported C structs and unions as addressable-for-dependencies
2542+
// so that Swift lifetime dependencies are more readily interoperable
2543+
// with pointers in C used for similar purposes.
2544+
properties.setAddressableForDependencies();
25402545
}
25412546
}
25422547

test/Interop/Cxx/class/nonescapable-lifetimebound.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,20 +116,20 @@ namespace NS {
116116
}
117117

118118
// CHECK: sil [clang makeOwner] {{.*}}: $@convention(c) () -> Owner
119-
// CHECK: sil [clang getView] {{.*}} : $@convention(c) (@in_guaranteed Owner) -> @lifetime(borrow 0) @owned View
120-
// CHECK: sil [clang getViewFromFirst] {{.*}} : $@convention(c) (@in_guaranteed Owner, @in_guaranteed Owner) -> @lifetime(borrow 0) @owned View
121-
// CHECK: sil [clang getViewFromEither] {{.*}} : $@convention(c) (@in_guaranteed Owner, @in_guaranteed Owner) -> @lifetime(borrow 0, borrow 1) @owned View
119+
// CHECK: sil [clang getView] {{.*}} : $@convention(c) (@in_guaranteed Owner) -> @lifetime(borrow address_for_deps 0) @owned View
120+
// CHECK: sil [clang getViewFromFirst] {{.*}} : $@convention(c) (@in_guaranteed Owner, @in_guaranteed Owner) -> @lifetime(borrow address_for_deps 0) @owned View
121+
// CHECK: sil [clang getViewFromEither] {{.*}} : $@convention(c) (@in_guaranteed Owner, @in_guaranteed Owner) -> @lifetime(borrow address_for_deps 0, borrow address_for_deps 1) @owned View
122122
// CHECK: sil [clang Owner.handOutView] {{.*}} : $@convention(cxx_method) (@in_guaranteed Owner) -> @lifetime(borrow 0) @owned View
123123
// CHECK: sil [clang Owner.handOutView2] {{.*}} : $@convention(cxx_method) (View, @in_guaranteed Owner) -> @lifetime(borrow 1) @owned View
124124
// CHECK: sil [clang getViewFromEither] {{.*}} : $@convention(c) (View, View) -> @lifetime(copy 0, copy 1) @owned View
125125
// CHECK: sil [clang View.init] {{.*}} : $@convention(c) () -> @lifetime(immortal) @out View
126126
// CHECK: sil [clang OtherView.init] {{.*}} : $@convention(c) (View) -> @lifetime(copy 0) @out OtherView
127127
// CHECK: sil [clang returnsImmortal] {{.*}} : $@convention(c) () -> @lifetime(immortal) @owned View
128128
// CHECK: sil [clang copyView] {{.*}} : $@convention(c) (View, @lifetime(copy 0) @inout View) -> ()
129-
// CHECK: sil [clang getCaptureView] {{.*}} : $@convention(c) (@in_guaranteed Owner) -> @lifetime(borrow 0) @owned CaptureView
129+
// CHECK: sil [clang getCaptureView] {{.*}} : $@convention(c) (@in_guaranteed Owner) -> @lifetime(borrow address_for_deps 0) @owned CaptureView
130130
// CHECK: sil [clang CaptureView.captureView] {{.*}} : $@convention(cxx_method) (View, @lifetime(copy 0) @inout CaptureView) -> ()
131131
// CHECK: sil [clang CaptureView.handOut] {{.*}} : $@convention(cxx_method) (@lifetime(copy 1) @inout View, @in_guaranteed CaptureView) -> ()
132-
// CHECK: sil [clang NS.getView] {{.*}} : $@convention(c) (@in_guaranteed Owner) -> @lifetime(borrow 0) @owned View
132+
// CHECK: sil [clang NS.getView] {{.*}} : $@convention(c) (@in_guaranteed Owner) -> @lifetime(borrow address_for_deps 0) @owned View
133133

134134
//--- test.swift
135135

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
struct CStruct { int x; int y; };
2+
union CUnion { int x; int y; };
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-swift-emit-silgen -import-objc-header %S/Inputs/clang_records_addressable_for_dependencies.h -enable-experimental-feature Lifetimes %s | %FileCheck %s
2+
3+
// REQUIRES: swift_feature_Lifetimes
4+
5+
struct Dependent: ~Escapable {
6+
@_lifetime(immortal)
7+
init() { fatalError() }
8+
}
9+
10+
// CHECK-LABEL: sil {{.*}} @${{.*}}12dependenceOn7cStruct{{.*}} : $@convention(thin) (@in_guaranteed CStruct)
11+
@_lifetime(cStruct)
12+
func dependenceOn(cStruct: CStruct) -> Dependent { fatalError() }
13+
14+
// CHECK-LABEL: sil {{.*}} @${{.*}}12dependenceOn6cUnion{{.*}} : $@convention(thin) (@in_guaranteed CUnion)
15+
@_lifetime(cUnion)
16+
func dependenceOn(cUnion: CUnion) -> Dependent { fatalError() }

0 commit comments

Comments
 (0)