blob: 53fbf6911508b81468e35df903c886e848d25d46 [file] [log] [blame]
// RUN: %target-sil-opt -module-name Swift -enable-sil-verify-all=0 -o /dev/null 2>&1 %s
// REQUIRES: asserts
// This file is meant to contain dataflow tests that if they fail are false
// positives.
//////////////////
// Declarations //
//////////////////
sil_stage canonical
import Builtin
protocol Error {}
sil @in_guaranteed_user : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
sil @error_func : $@convention(thin) () -> (Builtin.Int32, @error Error)
sil @allocate_object : $@convention(thin) () -> (@owned Builtin.NativeObject)
///////////
// Tests //
///////////
sil [ossa] @leak_loop_test : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : @owned $Builtin.NativeObject):
%1 = alloc_stack $Builtin.NativeObject
%2 = begin_borrow %0 : $Builtin.NativeObject
store_borrow %2 to %1 : $*Builtin.NativeObject
%3 = function_ref @in_guaranteed_user : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
apply %3(%1) : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
end_borrow %2 : $Builtin.NativeObject
dealloc_stack %1 : $*Builtin.NativeObject
br bb1
bb1:
cond_br undef, bb2, bb5
bb2:
cond_br undef, bb3, bb4
bb3:
br bb1
bb4:
br bb1
bb5:
destroy_value %0 : $Builtin.NativeObject
%9999 = tuple()
return %9999 : $()
}
// This test makes sure in the context of arguments, that if we have one
// lifetime ending user and that lifetime ending user is in the same block as
// the producer, we do not consider the predecessor blocks where our value is
// not defined. In the following test case, the bad predecessor is bb0.
sil [ossa] @single_block_consume_with_arg_and_unreachable : $@convention(thin) () -> () {
bb0:
%0 = function_ref @error_func : $@convention(thin) () -> (Builtin.Int32, @error Error)
try_apply %0() : $@convention(thin) () -> (Builtin.Int32, @error Error), normal bb1, error bb2
bb1(%2 : $Builtin.Int32):
%9999 = tuple()
return %9999 : $()
bb2(%3 : @owned $Error):
destroy_value %3 : $Error
unreachable
}
// This test makes sure in the context of instructions that produce new owned
// values, that if we have one lifetime ending user and that lifetime ending
// user is in the same block as the producer, we do not consider the predecessor
// blocks where our value is not defined. In the following test case, the bad
// predecessor is bb0.
sil [ossa] @single_block_consume_with_allocated_arg_and_unreachable : $@convention(thin) () -> () {
bb0:
cond_br undef, bb1, bb2
bb1:
%9999 = tuple()
return %9999 : $()
bb2:
%0 = function_ref @allocate_object : $@convention(thin) () -> (@owned Builtin.NativeObject)
%1 = apply %0() : $@convention(thin) () -> (@owned Builtin.NativeObject)
destroy_value %1 : $Builtin.NativeObject
unreachable
}
// This test makes sure in the context of instructions in a diamond that produce
// new owned values, that if we have one lifetime ending user and that lifetime
// ending user is in the same block as the producer, we do not consider the
// predecessor blocks where our value is not defined. In the following test
// case, the bad predecessor is bb0.
sil [ossa] @single_block_consume_with_diamond : $@convention(thin) () -> () {
bb0:
cond_br undef, bb1, bb2
bb1:
br bb3
bb2:
%0 = function_ref @allocate_object : $@convention(thin) () -> (@owned Builtin.NativeObject)
%1 = apply %0() : $@convention(thin) () -> (@owned Builtin.NativeObject)
destroy_value %1 : $Builtin.NativeObject
br bb3
bb3:
%9999 = tuple()
return %9999 : $()
}
// This test makes sure that we do not consider successors of our lifetime
// ending users as successors that we must visit. The target block is bb4.
sil [ossa] @multiple_block_consume_with_diamond : $@convention(thin) () -> () {
bb0:
cond_br undef, bb1, bb4
bb1:
%0 = function_ref @allocate_object : $@convention(thin) () -> (@owned Builtin.NativeObject)
%1 = apply %0() : $@convention(thin) () -> (@owned Builtin.NativeObject)
cond_br undef, bb2, bb3
bb2:
destroy_value %1 : $Builtin.NativeObject
br bb5
bb3:
destroy_value %1 : $Builtin.NativeObject
br bb4
bb4:
br bb5
bb5:
%9999 = tuple()
return %9999 : $()
}