mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
491 lines
16 KiB
Plaintext
491 lines
16 KiB
Plaintext
// RUN: %target-sil-opt -o /dev/null %s
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
|
|
// These are patterns that we should never consider as broken. For positive
|
|
// patterns look next door for verifier error checks.
|
|
|
|
sil @inoutCallee : $@convention(thin) (@inout Builtin.NativeObject) -> ()
|
|
sil @guaranteedUser : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
|
|
sil @useRawPointer : $@convention(thin) (Builtin.RawPointer) -> ()
|
|
|
|
//////////////////////////
|
|
// InOut Argument Tests //
|
|
//////////////////////////
|
|
|
|
sil [ossa] @inout_earlier_user_same_block : $@convention(thin) (@inout Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject):
|
|
%inout_user = function_ref @inoutCallee : $@convention(thin) (@inout Builtin.NativeObject) -> ()
|
|
br bb1
|
|
|
|
bb1:
|
|
apply %inout_user(%0) : $@convention(thin) (@inout Builtin.NativeObject) -> ()
|
|
%2 = load_borrow %0 : $*Builtin.NativeObject
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
br bb2
|
|
|
|
bb2:
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @inout_earlier_user_different_block : $@convention(thin) (@inout Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject):
|
|
%inout_user = function_ref @inoutCallee : $@convention(thin) (@inout Builtin.NativeObject) -> ()
|
|
br bb1
|
|
|
|
bb1:
|
|
apply %inout_user(%0) : $@convention(thin) (@inout Builtin.NativeObject) -> ()
|
|
br bb2
|
|
|
|
bb2:
|
|
%2 = load_borrow %0 : $*Builtin.NativeObject
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @inout_later_user_same_block : $@convention(thin) (@inout Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject):
|
|
%inout_user = function_ref @inoutCallee : $@convention(thin) (@inout Builtin.NativeObject) -> ()
|
|
br bb1
|
|
|
|
bb1:
|
|
%2 = load_borrow %0 : $*Builtin.NativeObject
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
apply %inout_user(%0) : $@convention(thin) (@inout Builtin.NativeObject) -> ()
|
|
br bb2
|
|
|
|
bb2:
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @inout_later_user_different_block : $@convention(thin) (@inout Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject):
|
|
%inout_user = function_ref @inoutCallee : $@convention(thin) (@inout Builtin.NativeObject) -> ()
|
|
br bb1
|
|
|
|
bb1:
|
|
%2 = load_borrow %0 : $*Builtin.NativeObject
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
br bb2
|
|
|
|
bb2:
|
|
apply %inout_user(%0) : $@convention(thin) (@inout Builtin.NativeObject) -> ()
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
|
|
////////////////////////
|
|
// Begin Access Tests //
|
|
////////////////////////
|
|
|
|
// Read tests
|
|
|
|
sil [ossa] @begin_access_read_write_before_same_block : $@convention(thin) (@inout Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
|
|
br bb1
|
|
|
|
bb1:
|
|
store %1 to [assign] %0 : $*Builtin.NativeObject
|
|
%3 = begin_access [read] [unsafe] %0 : $*Builtin.NativeObject
|
|
%2 = load_borrow %3 : $*Builtin.NativeObject
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
end_access %3 : $*Builtin.NativeObject
|
|
br bb2
|
|
|
|
bb2:
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @begin_access_read_write_after_same_block : $@convention(thin) (@inout Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
|
|
br bb1
|
|
|
|
bb1:
|
|
%3 = begin_access [read] [unsafe] %0 : $*Builtin.NativeObject
|
|
%2 = load_borrow %3 : $*Builtin.NativeObject
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
end_access %3 : $*Builtin.NativeObject
|
|
store %1 to [assign] %0 : $*Builtin.NativeObject
|
|
br bb2
|
|
|
|
bb2:
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// Modify tests
|
|
|
|
sil [ossa] @begin_access_modify_write_before_same_block : $@convention(thin) (@inout Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
|
|
br bb1
|
|
|
|
bb1:
|
|
store %1 to [assign] %0 : $*Builtin.NativeObject
|
|
%3 = begin_access [modify] [unsafe] %0 : $*Builtin.NativeObject
|
|
%2 = load_borrow %3 : $*Builtin.NativeObject
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
end_access %3 : $*Builtin.NativeObject
|
|
br bb2
|
|
|
|
bb2:
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
|
|
sil [ossa] @begin_access_modify_write_before_different_block : $@convention(thin) (@inout Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
|
|
store %1 to [assign] %0 : $*Builtin.NativeObject
|
|
br bb1
|
|
|
|
bb1:
|
|
%3 = begin_access [modify] [unsafe] %0 : $*Builtin.NativeObject
|
|
%2 = load_borrow %3 : $*Builtin.NativeObject
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
end_access %3 : $*Builtin.NativeObject
|
|
br bb2
|
|
|
|
bb2:
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @begin_access_modify_write_after_same_block : $@convention(thin) (@inout Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
|
|
br bb1
|
|
|
|
bb1:
|
|
%3 = begin_access [modify] [unsafe] %0 : $*Builtin.NativeObject
|
|
%2 = load_borrow %3 : $*Builtin.NativeObject
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
end_access %3 : $*Builtin.NativeObject
|
|
store %1 to [assign] %0 : $*Builtin.NativeObject
|
|
br bb2
|
|
|
|
bb2:
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @begin_access_modify_write_after_different_block : $@convention(thin) (@inout Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
|
|
br bb1
|
|
|
|
bb1:
|
|
%3 = begin_access [modify] [unsafe] %0 : $*Builtin.NativeObject
|
|
%2 = load_borrow %3 : $*Builtin.NativeObject
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
end_access %3 : $*Builtin.NativeObject
|
|
br bb2
|
|
|
|
bb2:
|
|
store %1 to [assign] %0 : $*Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// [modify] Writes in scope
|
|
|
|
sil [ossa] @begin_access_modify_same_scope_write_before_same_block : $@convention(thin) (@inout Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
|
|
br bb1
|
|
|
|
bb1:
|
|
%3 = begin_access [modify] [unsafe] %0 : $*Builtin.NativeObject
|
|
store %1 to [assign] %3 : $*Builtin.NativeObject
|
|
%2 = load_borrow %3 : $*Builtin.NativeObject
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
end_access %3 : $*Builtin.NativeObject
|
|
br bb2
|
|
|
|
bb2:
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
|
|
sil [ossa] @begin_access_modify_same_scope_write_before_different_block : $@convention(thin) (@inout Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
|
|
%3 = begin_access [modify] [unsafe] %0 : $*Builtin.NativeObject
|
|
store %1 to [assign] %3 : $*Builtin.NativeObject
|
|
br bb1
|
|
|
|
bb1:
|
|
%2 = load_borrow %3 : $*Builtin.NativeObject
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
end_access %3 : $*Builtin.NativeObject
|
|
br bb2
|
|
|
|
bb2:
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @begin_access_modify_same_scope_write_after_same_block : $@convention(thin) (@inout Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
|
|
br bb1
|
|
|
|
bb1:
|
|
%3 = begin_access [modify] [unsafe] %0 : $*Builtin.NativeObject
|
|
%2 = load_borrow %3 : $*Builtin.NativeObject
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
store %1 to [assign] %3 : $*Builtin.NativeObject
|
|
end_access %3 : $*Builtin.NativeObject
|
|
br bb2
|
|
|
|
bb2:
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @begin_access_modify_same_scope_write_after_different_block : $@convention(thin) (@inout Builtin.NativeObject, @owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
|
|
br bb1
|
|
|
|
bb1:
|
|
%3 = begin_access [modify] [unsafe] %0 : $*Builtin.NativeObject
|
|
%2 = load_borrow %3 : $*Builtin.NativeObject
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
br bb2
|
|
|
|
bb2:
|
|
store %1 to [assign] %3 : $*Builtin.NativeObject
|
|
end_access %3 : $*Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
//////////////////////////////
|
|
// pointer_to_address tests //
|
|
//////////////////////////////
|
|
|
|
sil [ossa] @pointer_to_address_test : $@convention(thin) (Builtin.RawPointer) -> () {
|
|
bb0(%0 : $Builtin.RawPointer):
|
|
%1 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*Builtin.NativeObject
|
|
%2 = load_borrow %1 : $*Builtin.NativeObject
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
////////////////////////
|
|
// Address Cast Tests //
|
|
////////////////////////
|
|
|
|
sil [ossa] @unconditional_checked_cast_addr_test : $@convention(thin) (@in Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject):
|
|
%0a = load_borrow %0 : $*Builtin.NativeObject
|
|
end_borrow %0a : $Builtin.NativeObject
|
|
|
|
%stack0 = alloc_stack $Builtin.NativeObject
|
|
unconditional_checked_cast_addr Builtin.NativeObject in %0 : $*Builtin.NativeObject to Builtin.NativeObject in %stack0 : $*Builtin.NativeObject
|
|
destroy_addr %stack0 : $*Builtin.NativeObject
|
|
dealloc_stack %stack0 : $*Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @conditional_addr_cast_always_take : $@convention(thin) (@in Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject):
|
|
%0a = load_borrow %0 : $*Builtin.NativeObject
|
|
end_borrow %0a : $Builtin.NativeObject
|
|
|
|
%stack0 = alloc_stack $Builtin.NativeObject
|
|
checked_cast_addr_br take_always Builtin.NativeObject in %0 : $*Builtin.NativeObject to Builtin.NativeObject in %stack0 : $*Builtin.NativeObject, bb1, bb2
|
|
|
|
bb1:
|
|
destroy_addr %stack0 : $*Builtin.NativeObject
|
|
br bb3
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
dealloc_stack %stack0 : $*Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @conditional_addr_cast_take_on_success : $@convention(thin) (@in Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject):
|
|
%0a = load_borrow %0 : $*Builtin.NativeObject
|
|
end_borrow %0a : $Builtin.NativeObject
|
|
|
|
%stack0 = alloc_stack $Builtin.NativeObject
|
|
checked_cast_addr_br take_on_success Builtin.NativeObject in %0 : $*Builtin.NativeObject to Builtin.NativeObject in %stack0 : $*Builtin.NativeObject, bb1, bb2
|
|
|
|
bb1:
|
|
destroy_addr %stack0 : $*Builtin.NativeObject
|
|
br bb3
|
|
|
|
bb2:
|
|
destroy_addr %0 : $*Builtin.NativeObject
|
|
br bb3
|
|
|
|
bb3:
|
|
dealloc_stack %stack0 : $*Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @conditional_addr_cast_copyonsuccess_1 : $@convention(thin) (@in Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject):
|
|
%0a = load_borrow %0 : $*Builtin.NativeObject
|
|
end_borrow %0a : $Builtin.NativeObject
|
|
|
|
%stack0 = alloc_stack $Builtin.NativeObject
|
|
checked_cast_addr_br copy_on_success Builtin.NativeObject in %0 : $*Builtin.NativeObject to Builtin.NativeObject in %stack0 : $*Builtin.NativeObject, bb1, bb2
|
|
|
|
bb1:
|
|
destroy_addr %stack0 : $*Builtin.NativeObject
|
|
br bb3
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
dealloc_stack %stack0 : $*Builtin.NativeObject
|
|
destroy_addr %0 : $*Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @conditional_addr_cast_copyonsuccess_2 : $@convention(thin) (@in Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject):
|
|
%0a = load_borrow %0 : $*Builtin.NativeObject
|
|
|
|
%stack0 = alloc_stack $Builtin.NativeObject
|
|
checked_cast_addr_br copy_on_success Builtin.NativeObject in %0 : $*Builtin.NativeObject to Builtin.NativeObject in %stack0 : $*Builtin.NativeObject, bb1, bb2
|
|
|
|
bb1:
|
|
destroy_addr %stack0 : $*Builtin.NativeObject
|
|
br bb3
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
dealloc_stack %stack0 : $*Builtin.NativeObject
|
|
end_borrow %0a : $Builtin.NativeObject
|
|
destroy_addr %0 : $*Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @pointer_to_address_is_assumed_to_be_safe : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : @owned $Builtin.NativeObject):
|
|
%1 = alloc_stack $Builtin.NativeObject
|
|
store %0 to [init] %1 : $*Builtin.NativeObject
|
|
%2 = load_borrow %1 : $*Builtin.NativeObject
|
|
%gUser = function_ref @guaranteedUser : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
|
|
apply %gUser(%2) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
%3 = address_to_pointer %1 : $*Builtin.NativeObject to $Builtin.RawPointer
|
|
%4 = mark_dependence %3 : $Builtin.RawPointer on %1 : $*Builtin.NativeObject
|
|
%rawPointerUser = function_ref @useRawPointer : $@convention(thin) (Builtin.RawPointer) -> ()
|
|
apply %rawPointerUser(%4) : $@convention(thin) (Builtin.RawPointer) -> ()
|
|
destroy_addr %1 : $*Builtin.NativeObject
|
|
dealloc_stack %1 : $*Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
struct Bool {
|
|
var _value: Builtin.Int1
|
|
}
|
|
|
|
sil [ossa] @test_withisunique : $@convention(method) <Element> (@inout Builtin.NativeObject) -> Bool {
|
|
bb0(%0 : $*Builtin.NativeObject):
|
|
%1 = is_unique %0 : $*Builtin.NativeObject
|
|
%2 = struct $Bool (%1 : $Builtin.Int1)
|
|
%3 = load_borrow %0 : $*Builtin.NativeObject
|
|
end_borrow %3 : $Builtin.NativeObject
|
|
return %2 : $Bool
|
|
}
|
|
|
|
sil [ossa] @test_valuemetatype : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : @owned $Builtin.NativeObject):
|
|
%1 = alloc_stack $Builtin.NativeObject
|
|
store %0 to [init] %1 : $*Builtin.NativeObject
|
|
%3a = value_metatype $@thick Builtin.NativeObject.Type, %1 : $*Builtin.NativeObject
|
|
%2 = load_borrow %1 : $*Builtin.NativeObject
|
|
%gUser = function_ref @guaranteedUser : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
|
|
apply %gUser(%2) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
|
|
end_borrow %2 : $Builtin.NativeObject
|
|
%3 = address_to_pointer %1 : $*Builtin.NativeObject to $Builtin.RawPointer
|
|
%4 = mark_dependence %3 : $Builtin.RawPointer on %1 : $*Builtin.NativeObject
|
|
%rawPointerUser = function_ref @useRawPointer : $@convention(thin) (Builtin.RawPointer) -> ()
|
|
apply %rawPointerUser(%4) : $@convention(thin) (Builtin.RawPointer) -> ()
|
|
destroy_addr %1 : $*Builtin.NativeObject
|
|
dealloc_stack %1 : $*Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
class KlassWithStruct {
|
|
var val : NonTrivialStruct
|
|
}
|
|
|
|
class Klass {
|
|
}
|
|
|
|
struct NonTrivialStruct {
|
|
var val : Klass
|
|
}
|
|
|
|
sil [ossa] @test_borrow : $@convention(thin) (@owned KlassWithStruct) -> () {
|
|
bb0(%0 : @owned $KlassWithStruct):
|
|
%2 = copy_value %0 : $KlassWithStruct
|
|
%4 = begin_borrow %2 : $KlassWithStruct
|
|
%5 = ref_element_addr %4 : $KlassWithStruct, #KlassWithStruct.val
|
|
%6 = load_borrow %5 : $*NonTrivialStruct
|
|
destroy_value %0 : $KlassWithStruct
|
|
end_borrow %6 : $NonTrivialStruct
|
|
end_borrow %4 : $KlassWithStruct
|
|
destroy_value %2 : $KlassWithStruct
|
|
%ret = tuple ()
|
|
return %ret : $()
|
|
}
|
|
|
|
sil [ossa] @test_overlapping_write1 : $@convention(method) (@guaranteed KlassWithStruct) -> () {
|
|
bb0(%0 : @guaranteed $KlassWithStruct):
|
|
%2 = copy_value %0 : $KlassWithStruct
|
|
%5 = ref_element_addr %0 : $KlassWithStruct, #KlassWithStruct.val
|
|
%6 = begin_access [read] [dynamic] %5 : $*NonTrivialStruct
|
|
%7 = load_borrow %6 : $*NonTrivialStruct
|
|
%11 = alloc_stack $KlassWithStruct
|
|
store %2 to [init] %11 : $*KlassWithStruct
|
|
destroy_addr %11 : $*KlassWithStruct
|
|
dealloc_stack %11 : $*KlassWithStruct
|
|
end_borrow %7 : $NonTrivialStruct
|
|
end_access %6 : $*NonTrivialStruct
|
|
%t = tuple ()
|
|
return %t : $()
|
|
}
|
|
|
|
sil [ossa] @test_overlapping_write2 : $@convention(method) (@guaranteed KlassWithStruct) -> () {
|
|
bb0(%0 : @guaranteed $KlassWithStruct):
|
|
%2 = copy_value %0 : $KlassWithStruct
|
|
%3 = begin_borrow %2 : $KlassWithStruct
|
|
%5 = ref_element_addr %3 : $KlassWithStruct, #KlassWithStruct.val
|
|
%6 = begin_access [read] [dynamic] %5 : $*NonTrivialStruct
|
|
%7 = load_borrow %6 : $*NonTrivialStruct
|
|
%11 = alloc_stack $KlassWithStruct
|
|
%12 = store_borrow %0 to %11 : $*KlassWithStruct
|
|
end_borrow %12 : $*KlassWithStruct
|
|
dealloc_stack %11 : $*KlassWithStruct
|
|
end_borrow %7 : $NonTrivialStruct
|
|
end_access %6 : $*NonTrivialStruct
|
|
end_borrow %3 : $KlassWithStruct
|
|
destroy_value %2 : $KlassWithStruct
|
|
%t = tuple ()
|
|
return %t : $()
|
|
}
|