Skip to content

Commit f44973f

Browse files
authored
Merge pull request #20079 from gottesmm/pr-b0fb5eb2f5151be44b6c9311c3d3fe015dc1fc5a
[closure-lifetime-fixup] When emitting a load_borrow, make sure to em…
2 parents 13cc0d0 + e4607a7 commit f44973f

File tree

7 files changed

+47
-6
lines changed

7 files changed

+47
-6
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,13 @@ class SILBuilder {
665665
BeginBorrowInst(getSILDebugLocation(Loc), LV));
666666
}
667667

668+
// Pass in an address or value, perform a begin_borrow/load_borrow and pass
669+
// the value to the passed in closure. After the closure has finished
670+
// executing, automatically insert the end_borrow. The closure can assume that
671+
// it will receive a loaded loadable value.
672+
void emitScopedBorrowOperation(SILLocation loc, SILValue original,
673+
function_ref<void(SILValue)> &&fun);
674+
668675
/// Utility function that returns a trivial store if the stored type is
669676
/// trivial and a \p Qualifier store if the stored type is non-trivial.
670677
///

lib/SIL/SILBuilder.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,3 +567,16 @@ DebugValueAddrInst *SILBuilder::createDebugValueAddr(SILLocation Loc,
567567
return insert(DebugValueAddrInst::create(getSILDebugLocation(Loc), src,
568568
getModule(), Var));
569569
}
570+
571+
void SILBuilder::emitScopedBorrowOperation(SILLocation loc, SILValue original,
572+
function_ref<void(SILValue)> &&fun) {
573+
if (original->getType().isAddress()) {
574+
original = createLoadBorrow(loc, original);
575+
} else {
576+
original = createBeginBorrow(loc, original);
577+
}
578+
579+
fun(original);
580+
581+
createEndBorrow(loc, original);
582+
}

lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -459,10 +459,12 @@ static bool fixupCopyBlockWithoutEscaping(CopyBlockWithoutEscapingInst *CB) {
459459

460460
for (auto LifetimeEndPoint : LifetimeEndPoints) {
461461
SILBuilderWithScope B(LifetimeEndPoint);
462-
auto IsEscaping =
463-
B.createIsEscapingClosure(Loc, B.createLoadBorrow(generatedLoc, Slot),
464-
IsEscapingClosureInst::ObjCEscaping);
465-
B.createCondFail(Loc, IsEscaping);
462+
SILValue isEscaping;
463+
B.emitScopedBorrowOperation(generatedLoc, Slot, [&](SILValue value) {
464+
isEscaping = B.createIsEscapingClosure(
465+
Loc, value, IsEscapingClosureInst::ObjCEscaping);
466+
});
467+
B.createCondFail(Loc, isEscaping);
466468
B.createDestroyAddr(generatedLoc, Slot);
467469
// Store None to it.
468470
B.createStore(generatedLoc,
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
#define SWIFT_NOESCAPE __attribute__((__noescape__))
3+
4+
typedef void (^block_t)(void);
5+
6+
block_t block_create_noescape(block_t SWIFT_NOESCAPE block);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
module ClosureLifetimeFixupObjC {
3+
header "closure_lifetime_fixup_objc.h"
4+
export *
5+
}

test/SILOptimizer/closure_lifetime_fixup.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend %s -emit-sil -o - | %FileCheck %s
1+
// RUN: %target-swift-frontend %s -sil-verify-all -enable-sil-ownership -emit-sil -o - | %FileCheck %s
22

33
func use_closure(_ c : () -> () ) {
44
c()

test/SILOptimizer/closure_lifetime_fixup_objc.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
// RUN: %target-swift-frontend %s -emit-sil -o - | %FileCheck %s
1+
// RUN: %target-swift-frontend %s -enable-sil-ownership -sil-verify-all -emit-sil -o - -I %S/Inputs/usr/include | %FileCheck %s
22
// REQUIRES: objc_interop
33

44
import Foundation
5+
import ClosureLifetimeFixupObjC
56

67
@objc
78
public protocol DangerousEscaper {
@@ -100,3 +101,10 @@ class C: NSObject {
100101
getDispatchQueue().sync(execute: { _ = self })
101102
}
102103
}
104+
105+
// Make sure that we obey ownership invariants when we emit load_borrow.
106+
internal typealias MyBlock = @convention(block) () -> Void
107+
func getBlock(noEscapeBlock: () -> Void ) -> MyBlock {
108+
return block_create_noescape(noEscapeBlock)
109+
}
110+

0 commit comments

Comments
 (0)