mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Type annotations for instruction operands are omitted, e.g. ``` %3 = struct $S(%1, %2) ``` Operand types are redundant anyway and were only used for sanity checking in the SIL parser. But: operand types _are_ printed if the definition of the operand value was not printed yet. This happens: * if the block with the definition appears after the block where the operand's instruction is located * if a block or instruction is printed in isolation, e.g. in a debugger The old behavior can be restored with `-Xllvm -sil-print-types`. This option is added to many existing test files which check for operand types in their check-lines.
210 lines
6.1 KiB
Plaintext
210 lines
6.1 KiB
Plaintext
// RUN: %target-sil-opt -sil-print-types -update-borrowed-from -enable-sil-verify-all %s | %FileCheck %s
|
|
|
|
// Test that the LoadBorrowImmutabilityChecker accepts these cases.
|
|
// The verification should not bail-out on these, but there's no way
|
|
// to check that.
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
public enum FakeOptional<T> {
|
|
case none
|
|
case some(T)
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_borrow_init_enum_addr : $@convention(thin) (@owned AnyObject) -> () {
|
|
// CHECK: bb0(%0 : @owned $AnyObject):
|
|
// CHECK: [[ALLOC:%.*]] = alloc_stack $Optional<AnyObject>
|
|
// CHECK: init_enum_data_addr [[ALLOC]] : $*Optional<AnyObject>, #Optional.some!enumelt
|
|
// CHECK: load_borrow [[ALLOC]] : $*Optional<AnyObject>
|
|
// CHECK-LABEL: } // end sil function 'test_borrow_init_enum_addr'
|
|
sil [ossa] @test_borrow_init_enum_addr : $@convention(thin) (@owned AnyObject) -> () {
|
|
bb0(%0 : @owned $AnyObject):
|
|
%1 = alloc_stack $Optional<AnyObject>
|
|
%2 = init_enum_data_addr %1 : $*Optional<AnyObject>, #Optional.some!enumelt
|
|
store %0 to [init] %2 : $*AnyObject
|
|
inject_enum_addr %1 : $*Optional<AnyObject>, #Optional.some!enumelt
|
|
%5 = load_borrow %1 : $*Optional<AnyObject>
|
|
end_borrow %5 : $Optional<AnyObject>
|
|
destroy_addr %1 : $*Optional<AnyObject>
|
|
dealloc_stack %1 : $*Optional<AnyObject>
|
|
%99 = tuple ()
|
|
return %99 : $()
|
|
}
|
|
|
|
// unchecked_ownership_conversion should not be considered a write to memory.
|
|
class ObjectWrapper {
|
|
var object: AnyObject
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @unchecked_ownership_conversion_test : $@convention(thin) (@guaranteed ObjectWrapper) -> @owned ObjectWrapper {
|
|
// CHECK: bb0(%0 : @guaranteed $ObjectWrapper):
|
|
// CHECK: load_borrow
|
|
// CHECK: unchecked_ownership_conversion %0 : $ObjectWrapper, @guaranteed to @owned
|
|
// CHECK: end_borrow
|
|
// CHECK-LABEL: } // end sil function 'unchecked_ownership_conversion_test'
|
|
sil [ossa] @unchecked_ownership_conversion_test : $@convention(thin) (@guaranteed ObjectWrapper) -> @owned ObjectWrapper {
|
|
bb0(%0 : @guaranteed $ObjectWrapper):
|
|
%1 = ref_element_addr %0 : $ObjectWrapper, #ObjectWrapper.object
|
|
%2 = load_borrow %1 : $*AnyObject
|
|
%3 = unchecked_ownership_conversion %0 : $ObjectWrapper, @guaranteed to @owned
|
|
end_borrow %2 : $AnyObject
|
|
return %3 : $ObjectWrapper
|
|
}
|
|
|
|
final class B { }
|
|
|
|
final class K {
|
|
@_hasStorage public var x: B { get }
|
|
init()
|
|
}
|
|
|
|
sil [ossa] @test_dealloc_ref : $@convention(thin) (@owned K) -> () {
|
|
bb0(%0 : @owned $K):
|
|
%1 = begin_borrow %0 : $K
|
|
%2 = ref_element_addr %1 : $K, #K.x
|
|
%3 = begin_access [read] [dynamic] %2 : $*B
|
|
%4 = load_borrow %3 : $*B
|
|
end_borrow %4 : $B
|
|
end_access %3 : $*B
|
|
end_borrow %1 : $K
|
|
dealloc_ref %0 : $K
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
sil [ossa] @test_dealloc_partial_ref : $@convention(thin) (@owned K) -> () {
|
|
bb0(%0 : @owned $K):
|
|
%1 = begin_borrow %0 : $K
|
|
%2 = ref_element_addr %1 : $K, #K.x
|
|
%3 = begin_access [read] [dynamic] %2 : $*B
|
|
%4 = load_borrow %3 : $*B
|
|
end_borrow %4 : $B
|
|
end_access %3 : $*B
|
|
end_borrow %1 : $K
|
|
%8 = metatype $@thick K.Type
|
|
dealloc_partial_ref %0 : $K, %8 : $@thick K.Type
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
sil [ossa] @test_end_lifetime : $@convention(thin) (@owned K) -> () {
|
|
bb0(%0 : @owned $K):
|
|
%1 = begin_borrow %0 : $K
|
|
%2 = ref_element_addr %1 : $K, #K.x
|
|
%3 = begin_access [read] [dynamic] %2 : $*B
|
|
%4 = load_borrow %3 : $*B
|
|
end_borrow %4 : $B
|
|
end_access %3 : $*B
|
|
%cast = unchecked_ref_cast %1 : $K to $Builtin.NativeObject
|
|
%conv1 = unchecked_ownership_conversion %cast : $Builtin.NativeObject, @guaranteed to @owned
|
|
end_borrow %1 : $K
|
|
end_lifetime %0 : $K
|
|
%conv2 = unchecked_ref_cast %conv1 : $Builtin.NativeObject to $K
|
|
dealloc_ref %conv2 : $K
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
sil @use_guaranteed : $@convention(thin) (@guaranteed K) -> ()
|
|
|
|
sil [ossa] @test_write_reborrow : $@convention(thin) (@owned K, @owned K) -> () {
|
|
bb0(%0 : @owned $K, %1 : @owned $K):
|
|
%stk = alloc_stack [lexical] $K
|
|
store %0 to [init] %stk : $*K
|
|
%ld1 = load_borrow %stk : $*K
|
|
br bb2(%ld1 : $K)
|
|
|
|
bb2(%ld : @guaranteed $K):
|
|
%3 = function_ref @use_guaranteed : $@convention(thin) (@guaranteed K) -> ()
|
|
%4 = apply %3(%ld) : $@convention(thin) (@guaranteed K) -> ()
|
|
end_borrow %ld : $K
|
|
store %1 to [assign] %stk : $*K
|
|
destroy_addr %stk : $*K
|
|
dealloc_stack %stk : $*K
|
|
%6 = tuple ()
|
|
return %6 : $()
|
|
}
|
|
|
|
sil [ossa] @test_multiple_loadborrows : $@convention(thin) (@owned K, @owned K) -> () {
|
|
bb0(%0 : @owned $K, %1 : @owned $K):
|
|
%stk = alloc_stack [lexical] $K
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
destroy_value %1 : $K
|
|
store %0 to [init] %stk : $*K
|
|
br bb3
|
|
|
|
bb2:
|
|
destroy_value %0 : $K
|
|
store %1 to [init] %stk : $*K
|
|
br bb3
|
|
|
|
bb3:
|
|
cond_br undef, bb4, bb5
|
|
|
|
bb4:
|
|
%ld1 = load_borrow %stk : $*K
|
|
br bb6(%ld1 : $K)
|
|
|
|
bb5:
|
|
%ld2 = load_borrow %stk : $*K
|
|
br bb6(%ld2 : $K)
|
|
|
|
bb6(%ld : @guaranteed $K):
|
|
%3 = function_ref @use_guaranteed : $@convention(thin) (@guaranteed K) -> ()
|
|
%4 = apply %3(%ld) : $@convention(thin) (@guaranteed K) -> ()
|
|
end_borrow %ld : $K
|
|
destroy_addr %stk : $*K
|
|
dealloc_stack %stk : $*K
|
|
%6 = tuple ()
|
|
return %6 : $()
|
|
}
|
|
|
|
sil [ossa] @test_multi_bb : $@convention(thin) (@inout FakeOptional<K>) -> () {
|
|
bb0(%0 : $*FakeOptional<K>):
|
|
%1 = begin_access [modify] [static] %0 : $*FakeOptional<K>
|
|
%2 = load_borrow %1 : $*FakeOptional<K>
|
|
%4 = copy_value %2 : $FakeOptional<K>
|
|
switch_enum %4 : $FakeOptional<K>, case #FakeOptional.some!enumelt: bb1, case #FakeOptional.none!enumelt: bb2
|
|
|
|
bb1(%6 : @owned $K):
|
|
destroy_value %6 : $K
|
|
end_borrow %2 : $FakeOptional<K>
|
|
end_access %1 : $*FakeOptional<K>
|
|
br bb3
|
|
|
|
bb2:
|
|
unreachable
|
|
|
|
bb3:
|
|
%12 = tuple ()
|
|
return %12 : $()
|
|
}
|
|
|
|
sil [ossa] @test_write_reborrow_loop : $@convention(thin) (@owned K) -> () {
|
|
bb0(%0 : @owned $K):
|
|
%stk = alloc_stack $K
|
|
store %0 to [init] %stk : $*K
|
|
%ld1 = load_borrow %stk : $*K
|
|
br bb1(%ld1 : $K)
|
|
|
|
bb1(%ld2 : @guaranteed $K):
|
|
cond_br undef, bb2, bb3
|
|
|
|
bb2:
|
|
%3 = function_ref @use_guaranteed : $@convention(thin) (@guaranteed K) -> ()
|
|
%4 = apply %3(%ld2) : $@convention(thin) (@guaranteed K) -> ()
|
|
br bb1(%ld2 : $K)
|
|
|
|
bb3:
|
|
end_borrow %ld2 : $K
|
|
destroy_addr %stk : $*K
|
|
dealloc_stack %stk : $*K
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|