Files
swift-mirror/test/SIL/OwnershipVerifier/load_borrow_verify.sil
Erik Eckstein 7cceaff5f3 SIL: don't print operand types in textual SIL
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.
2024-11-21 18:49:52 +01:00

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 : $()
}