Skip to content

Commit

Permalink
Fix LoadBorrowImmutabilityChecker for partial applies (swiftlang#34658)
Browse files Browse the repository at this point in the history
  • Loading branch information
meg-gupta authored Nov 12, 2020
1 parent 7d05f37 commit ce218b3
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
11 changes: 11 additions & 0 deletions lib/SIL/Verifier/LoadBorrowImmutabilityChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,17 @@ bool GatherWritesVisitor::visitUse(Operand *op, AccessUseType useTy) {
return false;
}

if (auto *pa = dyn_cast<PartialApplyInst>(user)) {
auto argConv = ApplySite(user).getArgumentConvention(*op);
if (argConv == SILArgumentConvention::Indirect_In_Guaranteed) {
return true;
}

// For all other conventions, the underlying address could be mutated
writeAccumulator.push_back(op);
return true;
}

// Handle a capture-by-address like a write.
if (auto as = ApplySite::isa(user)) {
writeAccumulator.push_back(op);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// RUN: %target-sil-opt -enable-sil-verify-all -inline %s -o /dev/null

// Tests here are patterns we should not consider as broken

import Builtin

class SuperKlass {}
class Klass : SuperKlass {}

struct WrapperStruct {
var cls : Klass
}

sil [ossa] @foo1 : $@convention(thin) (@guaranteed WrapperStruct, @in_guaranteed WrapperStruct) -> ()
sil [ossa] @foo2 : $@convention(thin) (@owned WrapperStruct, @in_guaranteed WrapperStruct) -> ()

sil [ossa] @test1 : $@convention(thin) (@in_guaranteed WrapperStruct) -> () {
bb0(%0 : $*WrapperStruct):
%1 = load_borrow %0 : $*WrapperStruct
%func = function_ref @foo1 : $@convention(thin) (@guaranteed WrapperStruct, @in_guaranteed WrapperStruct) -> ()
%pa = partial_apply [callee_guaranteed] [on_stack] %func(%1, %0) : $@convention(thin) (@guaranteed WrapperStruct, @in_guaranteed WrapperStruct) -> ()
end_borrow %1 : $WrapperStruct
dealloc_stack %pa : $@noescape @callee_guaranteed () -> ()
%res = tuple ()
return %res : $()
}

sil [ossa] @test2 : $@convention(thin) (@in_guaranteed WrapperStruct) -> () {
bb0(%0 : $*WrapperStruct):
%1 = load_borrow %0 : $*WrapperStruct
%copy = copy_value %1 : $WrapperStruct
%func = function_ref @foo2 : $@convention(thin) (@owned WrapperStruct, @in_guaranteed WrapperStruct) -> ()
%pa = partial_apply %func(%copy, %0) : $@convention(thin) (@owned WrapperStruct, @in_guaranteed WrapperStruct) -> ()
end_borrow %1 : $WrapperStruct
destroy_value %pa : $@callee_owned () -> ()
%res = tuple ()
return %res : $()
}

sil [ossa] @caller1 : $@convention(thin) (@owned WrapperStruct) -> () {
bb0(%0 : @owned $WrapperStruct):
%stk = alloc_stack $WrapperStruct
store %0 to [init] %stk : $*WrapperStruct
%func = function_ref @test1 : $@convention(thin) (@in_guaranteed WrapperStruct) -> ()
%a = apply %func(%stk) : $@convention(thin) (@in_guaranteed WrapperStruct) -> ()
destroy_addr %stk : $*WrapperStruct
dealloc_stack %stk : $*WrapperStruct
%res = tuple ()
return %res : $()
}

sil [ossa] @caller2 : $@convention(thin) (@owned WrapperStruct) -> () {
bb0(%0 : @owned $WrapperStruct):
%stk = alloc_stack $WrapperStruct
store %0 to [init] %stk : $*WrapperStruct
%func = function_ref @test2 : $@convention(thin) (@in_guaranteed WrapperStruct) -> ()
%a = apply %func(%stk) : $@convention(thin) (@in_guaranteed WrapperStruct) -> ()
destroy_addr %stk : $*WrapperStruct
dealloc_stack %stk : $*WrapperStruct
%res = tuple ()
return %res : $()
}

0 comments on commit ce218b3

Please sign in to comment.