blob: 4d3ab9d4df6ac146a5a8cce688c3664f88aeb5c5 [file] [log] [blame]
// RUN: %target-sil-opt -enable-sil-verify-all %s -enforce-exclusivity=unchecked -diagnose-static-exclusivity -verify -enable-sil-ownership | %FileCheck %s
//
// These tests are extensions of those in
// exclusivity_static_diagnostics.sil. Once those tests are rewritten
// with full ownership annotations, the files can be merged.
sil_stage raw
import Builtin
import Swift
// -----------------------------------------------------------------------------
// <rdar://problem/42242406> [SR-8266]: Compiler crash when checking
// exclusivity of inout alias closureWithNoCapture,
// closureWithConflict, partialApplyPhiThunk, and testPartialApplyPhi.
//
// Test that 'checkNoEscapePartialApply' does not assert on a noescape
// closure passed through a block argument.
sil hidden @closureWithNoCapture : $@convention(thin) (Int32) -> () {
bb0(%0 : @trivial $Int32):
%2 = tuple ()
return %2 : $()
}
sil hidden @closureWithConflict : $@convention(thin) (Int32, @inout_aliasable Int32) -> () {
bb0(%0 : @trivial $Int32, %1 : @trivial $*Int32):
// FIXME: a conflict should be reported here.
%2 = begin_access [modify] [unknown] %1 : $*Int32
end_access %2 : $*Int32
%v = tuple ()
return %v : $()
}
sil shared [transparent] [serializable] [reabstraction_thunk] @partialApplyPhiThunk : $@convention(thin) (@in_guaranteed Int32, @guaranteed @noescape @callee_guaranteed (Int32) -> (@error Error)) -> (@error Error) {
bb0(%0 : @trivial $*Int32, %1 : @trivial $@noescape @callee_guaranteed (Int32) -> (@error Error)):
%val = load [trivial] %0 : $*Int32
try_apply %1(%val) : $@noescape @callee_guaranteed (Int32) -> (@error Error), normal bb1, error bb2
bb1(%v : @trivial $()):
return %v : $()
bb2(%5 : @owned $Error):
throw %5 : $Error
}
sil @takeGenericNoEscapeFunction : $@convention(method) _0_0> (@inout τ_0_0, @noescape @callee_guaranteed (@in_guaranteed τ_0_0) -> (@error Error)) -> (@error Error)
// CHECK-LABEL: sil @testPartialApplyPhi
sil @testPartialApplyPhi : $@convention(thin) (Int, @inout Int32) -> (@error Error) {
bb0(%0 : @trivial $Int, %1 : @trivial $*Int32):
cond_br undef, bb1, bb2
bb1:
%f1 = function_ref @closureWithNoCapture : $@convention(thin) (Int32) -> ()
%pa1 = partial_apply [callee_guaranteed] %f1() : $@convention(thin) (Int32) -> ()
br bb3(%pa1 : $@callee_guaranteed (Int32) -> ())
bb2:
%f2 = function_ref @closureWithConflict : $@convention(thin) (Int32, @inout_aliasable Int32) -> ()
%pa2 = partial_apply [callee_guaranteed] %f2(%1) : $@convention(thin) (Int32, @inout_aliasable Int32) -> ()
br bb3(%pa2 : $@callee_guaranteed (Int32) -> ())
bb3(%pa3 : @owned $@callee_guaranteed (Int32) -> ()):
%cvt3 = convert_function %pa3 : $@callee_guaranteed (Int32) -> () to $@callee_guaranteed (Int32) -> (@error Error)
%esc3 = convert_escape_to_noescape [not_guaranteed] %cvt3 : $@callee_guaranteed (Int32) -> (@error Error) to $@noescape @callee_guaranteed (Int32) -> (@error Error)
%f3 = function_ref @partialApplyPhiThunk : $@convention(thin) (@in_guaranteed Int32, @guaranteed @noescape @callee_guaranteed (Int32) -> (@error Error)) -> (@error Error)
%pa4 = partial_apply [callee_guaranteed] %f3(%esc3) : $@convention(thin) (@in_guaranteed Int32, @guaranteed @noescape @callee_guaranteed (Int32) -> (@error Error)) -> (@error Error)
%esc4 = convert_escape_to_noescape [not_guaranteed] %pa4 : $@callee_guaranteed (@in_guaranteed Int32) -> (@error Error) to $@noescape @callee_guaranteed (@in_guaranteed Int32) -> (@error Error)
// In the original test case, the closures are destroyed before their use. Is that ok?
destroy_value %pa4 : $@callee_guaranteed (@in_guaranteed Int32) -> (@error Error)
destroy_value %cvt3 : $@callee_guaranteed (Int32) -> (@error Error)
// FIXME: a conflict should be reported here.
%access = begin_access [modify] [static] %1 : $*Int32
%f4 = function_ref @takeGenericNoEscapeFunction : $@convention(method) _0_0> (@inout τ_0_0, @noescape @callee_guaranteed (@in_guaranteed τ_0_0) -> (@error Error)) -> (@error Error)
try_apply %f4<Int32>(%access, %esc4) : $@convention(method) _0_0> (@inout τ_0_0, @noescape @callee_guaranteed (@in_guaranteed τ_0_0) -> (@error Error)) -> (@error Error), normal bb4, error bb5
bb4(%v : @trivial $()):
end_access %access : $*Int32
return %v : $()
bb5(%e : @owned $Error):
end_access %access : $*Int32
throw %e : $Error
}