@@ -21,6 +21,64 @@ class D {
21
21
}
22
22
}
23
23
24
+ class DataWrapper {
25
+
26
+ var pointer : UnsafeMutableRawBufferPointer
27
+
28
+ init ( count: Int ) {
29
+ pointer = UnsafeMutableRawBufferPointer . allocate ( byteCount: count, alignment: MemoryLayout< Int> . alignment)
30
+ }
31
+
32
+ var bytes : UnsafeMutableRawBufferPointer { return pointer }
33
+
34
+ deinit {
35
+ pointer. deallocate ( )
36
+ }
37
+ }
38
+
39
+ var fileHandleMap : [ Int32 : String ] = [ : ]
40
+
41
+ func openTheFile( _ path: String ) -> Int32 {
42
+ let fd : Int32 = 42
43
+ assert ( fileHandleMap [ fd] == nil )
44
+ fileHandleMap [ fd] = path
45
+ return fd
46
+ }
47
+
48
+ func closeTheFile( _ fd: Int32 ) {
49
+ fileHandleMap. removeValue ( forKey: fd)
50
+ }
51
+
52
+ func writeToTheFile( _ fd: Int32 ) {
53
+ assert ( fileHandleMap [ fd] != nil )
54
+ }
55
+
56
+ class FileHandleWrapper {
57
+
58
+ var handle : Int32 ? = nil
59
+
60
+ func open( path: String ) {
61
+ let fd = openTheFile ( path)
62
+ if fd >= 0 {
63
+ handle = fd
64
+ }
65
+ }
66
+
67
+ func close( ) {
68
+ if let fd = handle {
69
+ closeTheFile ( fd)
70
+ handle = nil
71
+ }
72
+ }
73
+
74
+ deinit {
75
+ if let fd = handle {
76
+ closeTheFile ( fd)
77
+ }
78
+ }
79
+ }
80
+
81
+
24
82
// =============================================================================
25
83
// = Declarations }} =
26
84
// =============================================================================
@@ -29,27 +87,71 @@ class D {
29
87
// = Tests {{ =
30
88
// =============================================================================
31
89
32
- func test_localLetKeepsObjectAliveBeyondCallToClassWithWeakReference ( ) {
90
+ func test_localLet_keepsObjectAliveBeyondCallToClassWithWeakReference ( ) {
33
91
let d = D ( )
34
92
let c = C ( d)
35
- // CHECK: cWillFoo{{.*}} test_localLetKeepsObjectAliveBeyondCallToClassWithWeakReference
93
+ // CHECK: cWillFoo{{.*}} test_localLet_keepsObjectAliveBeyondCallToClassWithWeakReference
36
94
c. foo ( #function)
37
95
}
38
96
39
- func test_localVarKeepsObjectAliveBeyondCallToClassWithWeakReference ( ) {
97
+ func test_localVar_keepsObjectAliveBeyondCallToClassWithWeakReference ( ) {
40
98
var d = D ( )
41
99
let c = C ( d)
42
- // CHECK: cWillFoo{{.*}} test_localVarKeepsObjectAliveBeyondCallToClassWithWeakReference
100
+ // CHECK: cWillFoo{{.*}} test_localVar_keepsObjectAliveBeyondCallToClassWithWeakReference
43
101
c. foo ( #function)
44
102
}
45
103
104
+ func test_localLet_keepsObjectAliveBeyondCallToClassWithPointer_doit( _ input: [ UInt8 ] ) {
105
+ let data = DataWrapper ( count: input. count)
106
+ data. bytes. copyBytes ( from: input)
107
+ }
108
+ func test_localLet_keepsObjectAliveBeyondCallToClassWithPointer( ) {
109
+ test_localLet_keepsObjectAliveBeyondCallToClassWithPointer_doit ( [ 1 , 2 , 3 , 4 , 50 ] )
110
+ }
111
+
112
+ func test_localVar_keepsObjectAliveBeyondCallToClassWithPointer_doit( _ input: [ UInt8 ] ) {
113
+ let data = DataWrapper ( count: input. count)
114
+ data. bytes. copyBytes ( from: input)
115
+ }
116
+ func test_localVar_keepsObjectAliveBeyondCallToClassWithPointer( ) {
117
+ test_localVar_keepsObjectAliveBeyondCallToClassWithPointer_doit ( [ 1 , 2 , 3 , 4 , 50 ] )
118
+ }
119
+
120
+ func test_localLet_keepsObjectAliveBeyondCallToSynchronizationPointFunction_doit( _ path: String ) {
121
+ var file = FileHandleWrapper ( )
122
+ file. open ( path: path)
123
+ // Retrieving 'fd' is the last use of 'file'
124
+ guard let fd = file. handle else { return }
125
+ // 'fd' has now been closed. The subsequent write will fail.
126
+ writeToTheFile ( fd)
127
+ }
128
+ func test_localLet_keepsObjectAliveBeyondCallToSynchronizationPointFunction( ) {
129
+ test_localLet_keepsObjectAliveBeyondCallToSynchronizationPointFunction_doit ( " blue " )
130
+ }
131
+
132
+ func test_localVar_keepsObjectAliveBeyondCallToSynchronizationPointFunction_doit( _ path: String ) {
133
+ var file = FileHandleWrapper ( )
134
+ file. open ( path: path)
135
+ // Retrieving 'fd' is the last use of 'file'
136
+ guard let fd = file. handle else { return }
137
+ // 'fd' has now been closed. The subsequent write will fail.
138
+ writeToTheFile ( fd)
139
+ }
140
+ func test_localVar_keepsObjectAliveBeyondCallToSynchronizationPointFunction( ) {
141
+ test_localVar_keepsObjectAliveBeyondCallToSynchronizationPointFunction_doit ( " blue " )
142
+ }
143
+
46
144
// =============================================================================
47
145
// = Tests }} =
48
146
// =============================================================================
49
147
50
148
func run( ) {
51
- test_localLetKeepsObjectAliveBeyondCallToClassWithWeakReference ( )
52
- test_localVarKeepsObjectAliveBeyondCallToClassWithWeakReference ( )
149
+ test_localLet_keepsObjectAliveBeyondCallToClassWithWeakReference ( )
150
+ test_localVar_keepsObjectAliveBeyondCallToClassWithWeakReference ( )
151
+ test_localLet_keepsObjectAliveBeyondCallToClassWithPointer ( )
152
+ test_localVar_keepsObjectAliveBeyondCallToClassWithPointer ( )
153
+ test_localLet_keepsObjectAliveBeyondCallToSynchronizationPointFunction ( )
154
+ test_localVar_keepsObjectAliveBeyondCallToSynchronizationPointFunction ( )
53
155
}
54
156
55
157
run ( )
0 commit comments