@@ -178,10 +178,17 @@ bool swift::findInnerTransitiveGuaranteedUses(
178
178
break ;
179
179
}
180
180
case OperandOwnership::Borrow:
181
- BorrowingOperand (use).visitExtendedScopeEndingUses ([&](Operand *endUse) {
182
- leafUse (endUse);
183
- return true ;
184
- });
181
+ // FIXME: visitExtendedScopeEndingUses can't return false here once dead
182
+ // borrows are disallowed.
183
+ if (!BorrowingOperand (use).visitExtendedScopeEndingUses (
184
+ [&](Operand *endUse) {
185
+ leafUse (endUse);
186
+ return true ;
187
+ })) {
188
+ // Special case for dead borrows. This is dangerous because clients
189
+ // don't expect a begin_borrow to be in the use list.
190
+ leafUse (use);
191
+ }
185
192
break ;
186
193
}
187
194
}
@@ -275,10 +282,17 @@ bool swift::findInnerTransitiveGuaranteedUsesOfBorrowedValue(
275
282
break ;
276
283
}
277
284
case OperandOwnership::Borrow:
278
- BorrowingOperand (use).visitExtendedScopeEndingUses ([&](Operand *endUse) {
279
- recordUse (endUse);
280
- return true ;
281
- });
285
+ // FIXME: visitExtendedScopeEndingUses can't return false here once dead
286
+ // borrows are disallowed.
287
+ if (!BorrowingOperand (use).visitExtendedScopeEndingUses (
288
+ [&](Operand *endUse) {
289
+ recordUse (endUse);
290
+ return true ;
291
+ })) {
292
+ // Special case for dead borrows. This is dangerous because clients
293
+ // don't expect a begin_borrow to be in the use list.
294
+ recordUse (use);
295
+ }
282
296
break ;
283
297
}
284
298
}
@@ -427,21 +441,29 @@ bool BorrowingOperand::visitScopeEndingUses(
427
441
switch (kind) {
428
442
case BorrowingOperandKind::Invalid:
429
443
llvm_unreachable (" Using invalid case" );
430
- case BorrowingOperandKind::BeginBorrow:
444
+ case BorrowingOperandKind::BeginBorrow: {
445
+ bool deadBorrow = true ;
431
446
for (auto *use : cast<BeginBorrowInst>(op->getUser ())->getUses ()) {
432
447
if (use->isLifetimeEnding ()) {
448
+ deadBorrow = false ;
433
449
if (!func (use))
434
450
return false ;
435
451
}
436
452
}
437
- return true ;
453
+ // FIXME: special case for dead borrows. This is dangerous because clients
454
+ // only expect visitScopeEndingUses to return false if the visitor returned
455
+ // false.
456
+ return !deadBorrow;
457
+ }
438
458
case BorrowingOperandKind::BeginApply: {
459
+ bool deadApply = true ;
439
460
auto *user = cast<BeginApplyInst>(op->getUser ());
440
461
for (auto *use : user->getTokenResult ()->getUses ()) {
462
+ deadApply = false ;
441
463
if (!func (use))
442
464
return false ;
443
465
}
444
- return true ;
466
+ return !deadApply ;
445
467
}
446
468
// These are instantaneous borrow scopes so there aren't any special end
447
469
// scope instructions.
@@ -450,12 +472,16 @@ bool BorrowingOperand::visitScopeEndingUses(
450
472
case BorrowingOperandKind::Yield:
451
473
return true ;
452
474
case BorrowingOperandKind::Branch: {
475
+ bool deadBranch = true ;
453
476
auto *br = cast<BranchInst>(op->getUser ());
454
- for (auto *use : br->getArgForOperand (op)->getUses ())
455
- if (use->isLifetimeEnding ())
477
+ for (auto *use : br->getArgForOperand (op)->getUses ()) {
478
+ if (use->isLifetimeEnding ()) {
479
+ deadBranch = false ;
456
480
if (!func (use))
457
481
return false ;
458
- return true ;
482
+ }
483
+ }
484
+ return !deadBranch;
459
485
}
460
486
}
461
487
llvm_unreachable (" Covered switch isn't covered" );
@@ -522,10 +548,15 @@ BorrowedValue BorrowingOperand::getBorrowIntroducingUserResult() {
522
548
void BorrowingOperand::getImplicitUses (
523
549
SmallVectorImpl<Operand *> &foundUses,
524
550
std::function<void (Operand *)> *errorFunction) const {
525
- visitScopeEndingUses ([&](Operand *op) {
526
- foundUses.push_back (op);
551
+ // FIXME: this visitScopeEndingUses should never return false once dead
552
+ // borrows are disallowed.
553
+ if (!visitScopeEndingUses ([&](Operand *endOp) {
554
+ foundUses.push_back (endOp);
527
555
return true ;
528
- });
556
+ })) {
557
+ // Special-case for dead borrows.
558
+ foundUses.push_back (op);
559
+ }
529
560
}
530
561
531
562
// ===----------------------------------------------------------------------===//
0 commit comments