(Self) -> () -> (), %13 : $*@opened("5E7A6328-EF75-11E9-A383-D0817AD3F637", P) Self : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
%15 = apply %14<@opened("5E7A6328-EF75-11E9-A383-D0817AD3F637", P) Self>(%13) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
destroy_addr %2 : $*Optional
destroy_addr %10 : $*P
dealloc_stack %10 : $*P
dealloc_stack %2 : $*Optional
br bb2
bb2:
%23 = tuple ()
return %23 : $()
bb3:
destroy_addr %2 : $*Optional
dealloc_stack %2 : $*Optional
br bb2
}
// CHECK-LABEL: sil @open_existential_addr_blocks_optimization : $@convention(thin) () -> () {
// CHECK: [[P:%.*]] = alloc_stack $any P
// CHECK: copy_addr {{.*}} to [init] [[P]]
// CHECK: }
sil @open_existential_addr_blocks_optimization : $@convention(thin) () -> () {
bb0:
%2 = alloc_stack $Optional
%3 = function_ref @getP : $@convention(thin) () -> @out Optional
%4 = apply %3(%2) : $@convention(thin) () -> @out Optional
cond_br undef, bb1, bb3
bb1:
%9 = unchecked_take_enum_data_addr %2 : $*Optional
, #Optional.some!enumelt
%10 = alloc_stack $P
copy_addr %9 to [init] %10 : $*P
destroy_addr %2 : $*Optional
%13 = open_existential_addr immutable_access %10 : $*P to $*@opened("6E7A6328-EF75-11E9-A383-D0817AD3F637", P) Self
%14 = witness_method $@opened("6E7A6328-EF75-11E9-A383-D0817AD3F637", P) Self, #P.foo : (Self) -> () -> (), %13 : $*@opened("6E7A6328-EF75-11E9-A383-D0817AD3F637", P) Self : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
%15 = apply %14<@opened("6E7A6328-EF75-11E9-A383-D0817AD3F637", P) Self>(%13) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
destroy_addr %10 : $*P
dealloc_stack %10 : $*P
dealloc_stack %2 : $*Optional
br bb2
bb2:
%23 = tuple ()
return %23 : $()
bb3:
destroy_addr %2 : $*Optional
dealloc_stack %2 : $*Optional
br bb2
}
// CHECK-LABEL: sil @witness_method_blocks_optimization : $@convention(thin) () -> () {
// CHECK: [[P:%.*]] = alloc_stack $any P
// CHECK: copy_addr {{.*}} to [init] [[P]]
// CHECK: }
sil @witness_method_blocks_optimization : $@convention(thin) () -> () {
bb0:
%2 = alloc_stack $Optional
%3 = function_ref @getP : $@convention(thin) () -> @out Optional
%4 = apply %3(%2) : $@convention(thin) () -> @out Optional
cond_br undef, bb1, bb3
bb1:
%9 = unchecked_take_enum_data_addr %2 : $*Optional
, #Optional.some!enumelt
%10 = alloc_stack $P
copy_addr %9 to [init] %10 : $*P
%13 = open_existential_addr immutable_access %10 : $*P to $*@opened("7E7A6328-EF75-11E9-A383-D0817AD3F637", P) Self
destroy_addr %2 : $*Optional
%14 = witness_method $@opened("7E7A6328-EF75-11E9-A383-D0817AD3F637", P) Self, #P.foo : (Self) -> () -> (), %13 : $*@opened("7E7A6328-EF75-11E9-A383-D0817AD3F637", P) Self : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
%15 = apply %14<@opened("7E7A6328-EF75-11E9-A383-D0817AD3F637", P) Self>(%13) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
destroy_addr %10 : $*P
dealloc_stack %10 : $*P
dealloc_stack %2 : $*Optional
br bb2
bb2:
%23 = tuple ()
return %23 : $()
bb3:
destroy_addr %2 : $*Optional
dealloc_stack %2 : $*Optional
br bb2
}
///////////////////////////////////////////////////////////////////////////////
// Test checkTempObjectDestroy
// Use-after free crashing an XCTest.
sil @takeGuaranteedObj : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
// Do not remove a copy that is released via a load (because
// TempRValueOpt is an address-based optimization does not know how to
// remove releases, and trying to do that would reduce to ARC
// optimization).
// CHECK-LABEL: sil @copyWithLoadRelease : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> () {
// CHECK: bb0(%0 : $*Builtin.NativeObject):
// CHECK: [[STK:%.*]] = alloc_stack $Builtin.NativeObject
// CHECK: copy_addr %0 to [init] [[STK]] : $*Builtin.NativeObject
// CHECK: [[VAL:%.*]] = load [[STK]] : $*Builtin.NativeObject
// CHECK: apply %{{.*}}([[VAL]]) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
// CHECK: release_value [[VAL]] : $Builtin.NativeObject
// CHECK: dealloc_stack [[STK]] : $*Builtin.NativeObject
// CHECK-LABEL: } // end sil function 'copyWithLoadRelease'
sil @copyWithLoadRelease : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> () {
bb0(%0 : $*Builtin.NativeObject):
%stk = alloc_stack $Builtin.NativeObject
copy_addr %0 to [init] %stk : $*Builtin.NativeObject
%obj = load %stk : $*Builtin.NativeObject
%f = function_ref @takeGuaranteedObj : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
%call = apply %f(%obj) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
release_value %obj : $Builtin.NativeObject
dealloc_stack %stk : $*Builtin.NativeObject
%v = tuple ()
return %v : $()
}
// CHECK-LABEL: sil @takeWithLoadRelease : $@convention(thin) (@in Builtin.NativeObject) -> () {
// CHECK: bb0(%0 : $*Builtin.NativeObject):
// CHECK: [[STK:%.*]] = alloc_stack $Builtin.NativeObject
// CHECK: copy_addr [take] %0 to [init] [[STK]] : $*Builtin.NativeObject
// CHECK: [[VAL:%.*]] = load [[STK]] : $*Builtin.NativeObject
// CHECK: apply %{{.*}}([[VAL]]) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
// CHECK: release_value [[VAL]] : $Builtin.NativeObject
// CHECK-LABEL: } // end sil function 'takeWithLoadRelease'
sil @takeWithLoadRelease : $@convention(thin) (@in Builtin.NativeObject) -> () {
bb0(%0 : $*Builtin.NativeObject):
%stk = alloc_stack $Builtin.NativeObject
copy_addr [take] %0 to [init] %stk : $*Builtin.NativeObject
%obj = load %stk : $*Builtin.NativeObject
%f = function_ref @takeGuaranteedObj : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
%call = apply %f(%obj) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
release_value %obj : $Builtin.NativeObject
dealloc_stack %stk : $*Builtin.NativeObject
%v = tuple ()
return %v : $()
}
// CHECK-LABEL: sil @eliminate_fix_lifetime_on_dest_copyaddr : $@convention(thin) (@inout Klass) -> () {
// CHECK-NOT: alloc_stack
// CHECK: fix_lifetime %0
// CHECK-NOT: alloc_stack
// CHECK: } // end sil function 'eliminate_fix_lifetime_on_dest_copyaddr'
sil @eliminate_fix_lifetime_on_dest_copyaddr : $@convention(thin) (@inout Klass) -> () {
bb0(%0 : $*Klass):
%3 = alloc_stack $Klass
copy_addr %0 to [init] %3 : $*Klass
fix_lifetime %3 : $*Klass
destroy_addr %3 : $*Klass
dealloc_stack %3 : $*Klass
%9999 = tuple()
return %9999 : $()
}
// CHECK-LABEL: sil @test_aliasing_modify_access
// CHECK: [[A:%.*]] = ref_element_addr [immutable] %0 : $Klass, #Klass.a
// CHECK-NOT: copy_addr
// CHECK: [[L:%.*]] = load [[A]]
// CHECK: return [[L]]
// CHECK: } // end sil function 'test_aliasing_modify_access'
sil @test_aliasing_modify_access : $@convention(thin) (@guaranteed Klass, @guaranteed Klass) -> @owned String {
bb0(%0 : $Klass, %1 : $Klass):
%2 = ref_element_addr [immutable] %0 : $Klass, #Klass.a
%3 = alloc_stack $String
copy_addr %2 to [init] %3 : $*String
%4 = ref_element_addr %1 : $Klass, #Klass.a
%5 = begin_access [modify] [dynamic] [no_nested_conflict] %4 : $*String
end_access %5 : $*String
%323 = load %3 : $*String
destroy_addr %3 : $*String
dealloc_stack %3 : $*String
return %323 : $String
}
// CHECK-LABEL: sil @dont_remove_copy_from_released_object
// CHECK: copy_addr
// CHECK-NEXT: strong_release %0
// CHECK: } // end sil function 'dont_remove_copy_from_released_object'
sil @dont_remove_copy_from_released_object : $@convention(thin) (@owned C) -> @owned String {
bb0(%0 : $C):
%1 = ref_element_addr [immutable] %0, #C.x
%2 = alloc_stack $String
copy_addr %1 to [init] %2
strong_release %0
%5 = load %2
retain_value %5
destroy_addr %2
dealloc_stack %2
return %5
}
// CHECK-LABEL: sil @dont_remove_copy_from_consumed_object
// CHECK: copy_addr
// CHECK: apply
// CHECK: } // end sil function 'dont_remove_copy_from_consumed_object'
sil @dont_remove_copy_from_consumed_object : $@convention(thin) (@owned C) -> @owned String {
bb0(%0 : $C):
%1 = ref_element_addr [immutable] %0, #C.x
%2 = alloc_stack $String
copy_addr %1 to [init] %2
%4 = function_ref @consume : $@convention(thin) (@owned C) -> ()
apply %4(%0) : $@convention(thin) (@owned C) -> ()
%5 = load %2
retain_value %5
destroy_addr %2
dealloc_stack %2
return %5
}
// CHECK-LABEL: sil [ossa] @dont_shrink_lifetime_of_mark_dependence_base
// CHECK: copy_addr
// CHECK: apply
// CHECK: } // end sil function 'dont_shrink_lifetime_of_mark_dependence_base'
sil [ossa] @dont_shrink_lifetime_of_mark_dependence_base : $@convention(thin) () -> () {
bb0:
%0 = alloc_stack $C
%1 = function_ref @initC : $@convention(thin) () -> @out C
%2 = apply %1(%0) : $@convention(thin) () -> @out C
%3 = alloc_stack [var_decl] $C, let, name "a"
copy_addr [take] %0 to [init] %3
%5 = function_ref @createKlass : $@convention(thin) () -> @owned Klass
%6 = apply %5() : $@convention(thin) () -> @owned Klass
%7 = mark_dependence [nonescaping] %6 on %3
destroy_value %7
destroy_addr %3
dealloc_stack %3
dealloc_stack %0
%12 = tuple ()
return %12
}