mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
EscapeUtils: consider that a pointer argument can escape a function call
Unlike addresses of indirect arguments, a pointer argument (e.g. `UnsafePointer`) can escape a function call. For example, it can be returned. Fixes a miscompile rdar://154124497
This commit is contained in:
@@ -640,7 +640,7 @@ fileprivate struct EscapeWalker<V: EscapeVisitor> : ValueDefUseWalker,
|
||||
}
|
||||
|
||||
// Indirect arguments cannot escape the function, but loaded values from such can.
|
||||
if !followLoads(at: path) {
|
||||
if argOp.value.type.isAddress && !followLoads(at: path) {
|
||||
if let beginApply = apply as? BeginApplyInst {
|
||||
// begin_apply can yield an address value.
|
||||
if !indirectResultEscapes(of: beginApply, path: path) {
|
||||
|
||||
@@ -984,3 +984,21 @@ bb0(%0 : $Int):
|
||||
return %9 : $()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: Address escape information for escaping_pointer_through_function:
|
||||
// CHECK: value: %1 = alloc_stack $Int
|
||||
// CHECK-NEXT: ==> %4 = apply undef(%3) : $@convention(thin) (Builtin.RawPointer) -> UnsafeMutableRawBufferPointer
|
||||
// CHECK-NEXT: ==> %5 = apply undef(%4) : $@convention(thin) (UnsafeMutableRawBufferPointer) -> ()
|
||||
// CHECK-NEXT: End function escaping_pointer_through_function
|
||||
sil [ossa] @escaping_pointer_through_function : $@convention(thin) (Int) -> () {
|
||||
bb0(%0 : $Int):
|
||||
%1 = alloc_stack $Int
|
||||
fix_lifetime %1
|
||||
%3 = address_to_pointer %1 to $Builtin.RawPointer
|
||||
%4 = apply undef(%3) : $@convention(thin) (Builtin.RawPointer) -> UnsafeMutableRawBufferPointer
|
||||
%5 = apply undef(%4) : $@convention(thin) (UnsafeMutableRawBufferPointer) -> ()
|
||||
dealloc_stack %1
|
||||
%7 = tuple ()
|
||||
return %7
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1776,3 +1776,24 @@ bb0(%0 : $*Builtin.FixedArray<10, Int>, %1 : $Int, %2 : $Int):
|
||||
return %6
|
||||
}
|
||||
|
||||
sil @forwardPtr : $@convention(thin) (Builtin.RawPointer) -> UnsafeMutableRawBufferPointer {
|
||||
[global: read]
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil [ossa] @escaping_pointer_through_function :
|
||||
// CHECK: [[LD:%.*]] = load [trivial] %1
|
||||
// CHECK: return [[LD]]
|
||||
// CHECK-LABEL: } // end sil function 'escaping_pointer_through_function'
|
||||
sil [ossa] @escaping_pointer_through_function : $@convention(thin) (Int) -> Int {
|
||||
bb0(%0 : $Int):
|
||||
%1 = alloc_stack $Int
|
||||
store %0 to [trivial] %1
|
||||
%3 = address_to_pointer %1 to $Builtin.RawPointer
|
||||
%4 = function_ref @forwardPtr : $@convention(thin) (Builtin.RawPointer) -> UnsafeMutableRawBufferPointer
|
||||
%5 = apply %4(%3) : $@convention(thin) (Builtin.RawPointer) -> UnsafeMutableRawBufferPointer
|
||||
%6 = apply undef(%5) : $@convention(thin) (UnsafeMutableRawBufferPointer) -> ()
|
||||
%7 = load [trivial] %1
|
||||
dealloc_stack %1
|
||||
return %7
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user