1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
// RUN: %target-sil-opt %s -access-storage-analysis-dump -enable-sil-verify-all -o /dev/null | %FileCheck %s
// This test depends on the _ArrayBuffer type.
// REQUIRES: OS=macosx || OS=iphoneos
sil_stage canonical
import Builtin
import Swift
import SwiftShims
class UnsafeThing {
deinit
}
class Container {
var fld : [UInt8]
}
sil_vtable Container {}
class Container2 {
var fld : [UnsafeThing]
}
sil_vtable Container2 {}
// CHECK-LABEL: @release_safe_array
// CHECK-NOT: unidentified accesses: modify
sil @release_safe_array : $@convention(thin) (@guaranteed Container) -> () {
bb0(%0 : $Container):
%1 = ref_element_addr %0 : $Container, #Container.fld
%2 = struct_element_addr %1 : $*Array<UInt8>, #Array._buffer
%3 = struct_element_addr %2 : $*_ArrayBuffer<UInt8>, #_ArrayBuffer._storage
%4 = struct_element_addr %3 : $*_BridgeStorage<__ContiguousArrayStorageBase>, #_BridgeStorage.rawValue
%5 = load %4 : $*Builtin.BridgeObject
strong_release %5: $Builtin.BridgeObject
%7 = unchecked_ref_cast %5 : $Builtin.BridgeObject to $__ContiguousArrayStorageBase
strong_release %7: $__ContiguousArrayStorageBase
%8 = init_existential_ref %7 : $__ContiguousArrayStorageBase : $__ContiguousArrayStorageBase, $AnyObject
strong_retain %8 : $AnyObject
%t = tuple ()
return %t : $()
}
// CHECK-LABEL: @release_unsafe_array
// CHECK: unidentified accesses: modify
sil @release_unsafe_array : $@convention(thin) (@guaranteed Container2) -> () {
bb0(%0 : $Container2):
%1 = ref_element_addr %0 : $Container2, #Container2.fld
%2 = struct_element_addr %1 : $*Array<UnsafeThing>, #Array._buffer
%3 = struct_element_addr %2 : $*_ArrayBuffer<UnsafeThing>, #_ArrayBuffer._storage
%4 = struct_element_addr %3 : $*_BridgeStorage<__ContiguousArrayStorageBase>, #_BridgeStorage.rawValue
%5 = load %4 : $*Builtin.BridgeObject
strong_release %5: $Builtin.BridgeObject
%t = tuple ()
return %t : $()
}
sil @someClosure : $@convention(thin) (@guaranteed UnsafeThing) -> ()
// CHECK-LABEL: @testCaptureDeinit
// CHECK: unidentified accesses: modify
// Releasing the closure will trigger the deinit of the captured class.
sil @testCaptureDeinit : $@convention(thin) (Int, @guaranteed UnsafeThing) -> () {
bb0(%0 : $Int, %u : $UnsafeThing):
%s1 = alloc_stack $Int
store %0 to %s1 : $*Int
%s2 = alloc_stack $Int
store %0 to %s2 : $*Int
%f = function_ref @someClosure : $@convention(thin) (@guaranteed UnsafeThing) -> ()
%pa = partial_apply [callee_guaranteed] %f(%u) : $@convention(thin) (@guaranteed UnsafeThing) -> ()
%access = begin_access [modify] [dynamic] %s1 : $*Int
strong_release %pa : $@callee_guaranteed () -> ()
end_access %access : $*Int
dealloc_stack %s2 : $*Int
dealloc_stack %s1 : $*Int
%v = tuple ()
return %v : $()
}
|