Skip to content

Commit 3df609f

Browse files
committed
[SILVerifier] Check lex borrows of box instances.
Require that lexical borrows of values which are instances of some SILBoxType guard the lifetime of vars or closure captures; that's to say, of AllocBoxInsts and SILFunctionArguments. Look through a few instructions types to find those: - copy_value - inserted by SILGen - begin_borrow - inserted during inlining - mark_uninitialized - inserted by SILGen
1 parent 7ed618f commit 3df609f

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2223,6 +2223,31 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
22232223
"Found load borrow that is invalidated by a local write?!");
22242224
}
22252225

2226+
void checkBeginBorrowInst(BeginBorrowInst *bbi) {
2227+
if (!bbi->isLexical())
2228+
return;
2229+
// Lexical begin_borrows of instances of some SILBoxType must derive from
2230+
// alloc_boxes or captures.
2231+
auto value = bbi->getOperand();
2232+
if (!value->getType().is<SILBoxType>())
2233+
return;
2234+
while (true) {
2235+
// Inlining may introduce additional begin_borrow instructions.
2236+
if (auto bbi = dyn_cast<BeginBorrowInst>(value))
2237+
value = bbi->getOperand();
2238+
// SILGen introduces copy_value instructions.
2239+
else if (auto cvi = dyn_cast<CopyValueInst>(value))
2240+
value = cvi->getOperand();
2241+
// SILGen inserts mark_uninitialized instructions of alloc_boxes.
2242+
else if (auto *mui = dyn_cast<MarkUninitializedInst>(value))
2243+
value = mui->getOperand();
2244+
else
2245+
break;
2246+
}
2247+
require(isa<AllocBoxInst>(value) || isa<SILFunctionArgument>(value),
2248+
"Lexical borrows of SILBoxTypes must be of vars or captures.");
2249+
}
2250+
22262251
void checkEndBorrowInst(EndBorrowInst *EBI) {
22272252
require(
22282253
F.hasOwnership(),

0 commit comments

Comments
 (0)