Files
swift-mirror/test/SIL/OwnershipVerifier/borrow_extract_validate.sil
Erik Eckstein e14c1d1f62 SIL, Optimizer: update and handle borrowed-from instructions
Compute, update and handle borrowed-from instruction in various utilities and passes.
Also, used borrowed-from to simplify `gatherBorrowIntroducers` and `gatherEnclosingValues`.
Replace those utilities by `Value.getBorrowIntroducers` and `Value.getEnclosingValues`, which return a lazily computed Sequence of borrowed/enclosing values.
2024-04-10 13:38:10 +02:00

232 lines
10 KiB
Plaintext

// RUN: %target-sil-opt -disable-swift-verification -sil-ownership-verifier-enable-testing -ownership-verifier-textual-error-dumper -enable-sil-verify-all=0 %s -o /dev/null 2>&1 | %FileCheck %s
// REQUIRES: asserts
import Builtin
import Swift
//////////////////
// Declarations //
//////////////////
class Klass {}
struct WrapperStruct {
var cls : Klass
}
sil shared [noinline] @blackhole_spl1 : $@convention(thin) (@guaranteed Klass) -> () {
bb0(%0 : $Klass):
%1 = tuple ()
return %1 : $()
}
// CHECK-NOT: Function: 'borrowed_extract_dominate_correct'
sil [ossa] @borrowed_extract_dominate_correct : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
%copy0 = copy_value %0 : $WrapperStruct
%borrow0 = begin_borrow %copy0 : $WrapperStruct
%elem0 = struct_extract %borrow0 : $WrapperStruct, #WrapperStruct.cls
%func = function_ref @blackhole_spl1 : $@convention(thin) (@guaranteed Klass) -> ()
%call1 = apply %func(%elem0) : $@convention(thin) (@guaranteed Klass) -> ()
end_borrow %borrow0 : $WrapperStruct
destroy_value %copy0 : $WrapperStruct
%ret = tuple ()
return %ret : $()
}
// CHECK-LABEL: Error#: 0. Begin Error in Function: 'borrowed_extract_dominate_incorrect'
// CHECK: Found outside of lifetime use?!
// CHECK: Value: %3 = begin_borrow %2 : $WrapperStruct
// CHECK: Consuming User: end_borrow %3 : $WrapperStruct
// CHECK: Non Consuming User: %7 = apply %6(%4) : $@convention(thin) (@guaranteed Klass) -> ()
// CHECK: Block: bb0
// CHECK-LABEL: Error#: 0. End Error in Function: 'borrowed_extract_dominate_incorrect'
// CHECK-NOT: Error#: {{[0-9][0-9]*}}. End Error in Function: 'borrowed_extract_dominate_incorrect'
sil [ossa] @borrowed_extract_dominate_incorrect : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
%copy0 = copy_value %0 : $WrapperStruct
%borrow0 = begin_borrow %copy0 : $WrapperStruct
%elem0 = struct_extract %borrow0 : $WrapperStruct, #WrapperStruct.cls
end_borrow %borrow0 : $WrapperStruct
%func = function_ref @blackhole_spl1 : $@convention(thin) (@guaranteed Klass) -> ()
%call1 = apply %func(%elem0) : $@convention(thin) (@guaranteed Klass) -> ()
destroy_value %copy0 : $WrapperStruct
%ret = tuple ()
return %ret : $()
}
// CHECK-NOT: Function: 'borrowed_extract_dominate_discrepency_simple_correct'
sil [ossa] @borrowed_extract_dominate_discrepency_simple_correct : $@convention(thin) (@guaranteed WrapperStruct) -> () {
bb0(%0 : @guaranteed $WrapperStruct):
%elem = struct_extract %0 : $WrapperStruct, #WrapperStruct.cls
br bb1(%elem : $Klass)
bb1(%phi : @guaranteed $Klass):
%res = tuple ()
return %res : $()
}
// CHECK-NOT: Function: 'simple_extract_as_phi_arg_incorrect'
sil [ossa] @simple_extract_as_phi_arg_incorrect : $@convention(thin) (@guaranteed WrapperStruct) -> () {
bb0(%0 : @guaranteed $WrapperStruct):
%elem = struct_extract %0 : $WrapperStruct, #WrapperStruct.cls
br bb1(%elem : $Klass)
bb1(%newelem : @guaranteed $Klass):
%res = tuple ()
return %res : $()
}
// CHECK-LABEL: Error#: 0. Begin Error in Function: 'borrowed_extract_dominate_discrepency_incorrect1'
// CHECK: Found outside of lifetime use?!
// CHECK: Value: %7 = argument of bb1 : $WrapperStruct
// CHECK: Consuming User: end_borrow %7 : $WrapperStruct
// CHECK: Non Consuming User: %10 = apply %9(%6) : $@convention(thin) (@guaranteed Klass) -> ()
// CHECK: Block: bb1
// CHECK-LABEL: Error#: 0. End Error in Function: 'borrowed_extract_dominate_discrepency_incorrect1'
sil [ossa] @borrowed_extract_dominate_discrepency_incorrect1 : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
%copy0 = copy_value %0 : $WrapperStruct
%borrow0 = begin_borrow %copy0 : $WrapperStruct
%elem0 = struct_extract %borrow0 : $WrapperStruct, #WrapperStruct.cls
br bb1(%elem0 : $Klass, %borrow0 : $WrapperStruct)
bb1(%elem : @guaranteed $Klass, %newborrow : @guaranteed $WrapperStruct):
end_borrow %newborrow : $WrapperStruct
%func = function_ref @blackhole_spl1 : $@convention(thin) (@guaranteed Klass) -> ()
%call1 = apply %func(%elem) : $@convention(thin) (@guaranteed Klass) -> ()
destroy_value %copy0 : $WrapperStruct
%ret = tuple ()
return %ret : $()
}
// CHECK-LABEL: Error#: 0. Begin Error in Function: 'borrowed_extract_dominate_discrepency_incorrect2'
// CHECK: Found outside of lifetime use?!
// CHECK: Value: %2 = copy_value %0 : $WrapperStruct
// CHECK: Consuming User: destroy_value %2 : $WrapperStruct
// CHECK: Non Consuming User: end_borrow %7 : $WrapperStruct
// CHECK: Block: bb1
// CHECK-LABEL: Error#: 0. End Error in Function: 'borrowed_extract_dominate_discrepency_incorrect2'
// CHECK-NOT: Error#: {{[0-9][0-9]*}}. End Error in Function: 'borrowed_extract_dominate_discrepency_incorrect2'
sil [ossa] @borrowed_extract_dominate_discrepency_incorrect2 : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
%copy0 = copy_value %0 : $WrapperStruct
%borrow0 = begin_borrow %copy0 : $WrapperStruct
%elem0 = struct_extract %borrow0 : $WrapperStruct, #WrapperStruct.cls
br bb1(%elem0 : $Klass, %borrow0 : $WrapperStruct)
bb1(%elem : @guaranteed $Klass, %newborrow : @guaranteed $WrapperStruct):
%func = function_ref @blackhole_spl1 : $@convention(thin) (@guaranteed Klass) -> ()
destroy_value %copy0 : $WrapperStruct
%call1 = apply %func(%elem) : $@convention(thin) (@guaranteed Klass) -> ()
end_borrow %newborrow : $WrapperStruct
%ret = tuple ()
return %ret : $()
}
// CHECK-NOT: Function: 'borrowed_extract_not_dominate_correct'
sil [ossa] @borrowed_extract_not_dominate_correct : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
cond_br undef, bb1, bb2
bb1:
%copy0 = copy_value %0 : $WrapperStruct
%borrow0 = begin_borrow %copy0 : $WrapperStruct
%elem0 = struct_extract %borrow0 : $WrapperStruct, #WrapperStruct.cls
br bb3(%elem0 : $Klass, %borrow0 : $WrapperStruct, %copy0 : $WrapperStruct)
bb2:
%copy1 = copy_value %1 : $WrapperStruct
%borrow1 = begin_borrow %copy1 : $WrapperStruct
%elem1 = struct_extract %borrow1 : $WrapperStruct, #WrapperStruct.cls
br bb3(%elem1 : $Klass, %borrow1 : $WrapperStruct, %copy1 : $WrapperStruct)
bb3(%elem : @guaranteed $Klass, %newborrow : @guaranteed $WrapperStruct, %newowned : @owned $WrapperStruct):
%func = function_ref @blackhole_spl1 : $@convention(thin) (@guaranteed Klass) -> ()
%call1 = apply %func(%elem) : $@convention(thin) (@guaranteed Klass) -> ()
end_borrow %newborrow : $WrapperStruct
destroy_value %newowned : $WrapperStruct
%ret = tuple ()
return %ret : $()
}
// CHECK-NOT: Error#: {{[0-9][0-9]*}}. End Error in Function: 'borrowed_extract_not_dominate_incorrect1'
sil [ossa] @borrowed_extract_not_dominate_incorrect1 : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
cond_br undef, bb1, bb2
bb1:
%copy0 = copy_value %0 : $WrapperStruct
%borrow0 = begin_borrow %copy0 : $WrapperStruct
%elem0 = struct_extract %borrow0 : $WrapperStruct, #WrapperStruct.cls
br bb3(%elem0 : $Klass, %borrow0 : $WrapperStruct, %copy0 : $WrapperStruct)
bb2:
%copy1 = copy_value %1 : $WrapperStruct
%borrow1 = begin_borrow %copy1 : $WrapperStruct
%elem1 = struct_extract %borrow1 : $WrapperStruct, #WrapperStruct.cls
br bb3(%elem1 : $Klass, %borrow1 : $WrapperStruct, %copy1 : $WrapperStruct)
bb3(%elem : @guaranteed $Klass, %newborrow : @guaranteed $WrapperStruct, %newowned : @owned $WrapperStruct):
%func = function_ref @blackhole_spl1 : $@convention(thin) (@guaranteed Klass) -> ()
%call1 = apply %func(%elem) : $@convention(thin) (@guaranteed Klass) -> ()
end_borrow %newborrow : $WrapperStruct
destroy_value %newowned : $WrapperStruct
%ret = tuple ()
return %ret : $()
}
// CHECK-NOT: Function: 'borrowed_extract_dominates_one_path'
sil [ossa] @borrowed_extract_dominates_one_path : $@convention(thin) (@guaranteed WrapperStruct, @guaranteed WrapperStruct) -> () {
bb0(%0 : @guaranteed $WrapperStruct, %1 : @guaranteed $WrapperStruct):
%copy1 = copy_value %1 : $WrapperStruct
%borrow1 = begin_borrow %copy1 : $WrapperStruct
%elem1 = struct_extract %borrow1 : $WrapperStruct, #WrapperStruct.cls
cond_br undef, bb1, bb2
bb1:
end_borrow %borrow1 : $WrapperStruct
%copy0 = copy_value %0 : $WrapperStruct
%borrow0 = begin_borrow %copy0 : $WrapperStruct
%elem0 = struct_extract %borrow0 : $WrapperStruct, #WrapperStruct.cls
br bb3(%elem0 : $Klass, %borrow0 : $WrapperStruct, %copy0 : $WrapperStruct)
bb2:
%copy2 = copy_value %1 : $WrapperStruct
br bb3(%elem1 : $Klass, %borrow1 : $WrapperStruct, %copy2 : $WrapperStruct)
bb3(%elem : @guaranteed $Klass, %newborrow : @guaranteed $WrapperStruct, %newowned : @owned $WrapperStruct):
end_borrow %newborrow : $WrapperStruct
destroy_value %newowned : $WrapperStruct
destroy_value %copy1 : $WrapperStruct
%ret = tuple ()
return %ret : $()
}
// CHECK-NOT: Function: 'borrowed_extract_dominates_one_path_loop'
sil [ossa] @borrowed_extract_dominates_one_path_loop : $@convention(thin) (@guaranteed WrapperStruct) -> () {
bb0(%0 : @guaranteed $WrapperStruct):
%1b = copy_value %0 : $WrapperStruct
%1a = begin_borrow %1b : $WrapperStruct
%elem0 = struct_extract %1a : $WrapperStruct, #WrapperStruct.cls
br bb1(%elem0 : $Klass, %1a : $WrapperStruct, %1b : $WrapperStruct)
bb1(%elem : @guaranteed $Klass, %2a : @guaranteed $WrapperStruct, %2b : @owned $WrapperStruct):
cond_br undef, bb2, bb3
bb2:
%3 = copy_value %2a : $WrapperStruct
%3a = begin_borrow %3 : $WrapperStruct
%elem1 = struct_extract %3a : $WrapperStruct, #WrapperStruct.cls
end_borrow %2a : $WrapperStruct
destroy_value %2b : $WrapperStruct
br bb1(%elem1 : $Klass, %3a : $WrapperStruct, %3 : $WrapperStruct)
bb3:
end_borrow %2a : $WrapperStruct
destroy_value %2b : $WrapperStruct
%9999 = tuple()
return %9999 : $()
}