SILGen: Fix positioning of store_borrow for addressable references to closure captures.

These get passed to the closure body in SIL as function arguments to the entry
point, so the alloc_stack necessarily has to appear inside of the value's lifetime,
and the store_borrow needs to be placed after that alloc_stack.
This commit is contained in:
Joe Groff
2025-07-28 17:04:49 -07:00
parent 6d3d51f0db
commit 42d1ca3338
2 changed files with 27 additions and 1 deletions

View File

@@ -2337,7 +2337,12 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
} else if (auto inst = value->getDefiningInstruction()) {
B.setInsertionPoint(inst->getParent(), std::next(inst->getIterator()));
} else if (auto arg = dyn_cast<SILArgument>(value)) {
B.setInsertionPoint(arg->getParent()->begin());
if (auto farg = dyn_cast<SILFunctionArgument>(value);
farg && farg->isClosureCapture()) {
B.setInsertionPoint(allocStack->getNextInstruction());
} else {
B.setInsertionPoint(arg->getParent()->begin());
}
} else {
llvm_unreachable("unexpected value source!");
}

View File

@@ -0,0 +1,21 @@
// RUN: %target-swift-emit-silgen -enable-experimental-feature AddressableParameters %s | %FileCheck %s
// REQUIRES: swift_feature_AddressableParameters
struct Foo {
var x, y, z: Int
init() { fatalError() }
@_addressableSelf
func foo() {}
}
func block(_: (Int) -> ()) {}
func test() {
let x = Foo()
block { (_) in x.foo() }
}
// ensure the closure properly nests the store_borrow after the alloc_stack:
// CHECK-LABEL: sil{{.*}} @${{.*}}4test{{.*}}U_ : $
// CHECK: [[STACK:%.*]] = alloc_stack
// CHECK-NEXT: store_borrow {{.*}} to [[STACK]]