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