|
61 | 61 |
|
62 | 62 | using namespace swift; |
63 | 63 |
|
| 64 | +// FIXME: remove this option after fixing: |
| 65 | +// rdar://145994924 (Mem2Reg calls lifetime completion without checking for |
| 66 | +// pointer escapes) |
| 67 | +llvm::cl::opt<bool> VerifyLifetimeCompletion( |
| 68 | + "verify-lifetime-completion", llvm::cl::init(false), |
| 69 | + llvm::cl::desc(".")); |
| 70 | + |
64 | 71 | static SILInstruction *endOSSALifetime(SILValue value, |
65 | 72 | OSSALifetimeCompletion::LifetimeEnd end, |
66 | 73 | SILBuilder &builder, |
@@ -493,8 +500,16 @@ bool OSSALifetimeCompletion::analyzeAndUpdateLifetime( |
493 | 500 | } |
494 | 501 | }; |
495 | 502 | Walker walker(*this, scopedAddress, boundary, liveness); |
496 | | - std::move(walker).walk(scopedAddress.value); |
497 | | - |
| 503 | + AddressUseKind result = walker.walk(scopedAddress.value); |
| 504 | + if (VerifyLifetimeCompletion && boundary != Boundary::Availability |
| 505 | + && result != AddressUseKind::NonEscaping) { |
| 506 | + llvm::errs() << "Incomplete liveness for:\n" << scopedAddress.value; |
| 507 | + if (auto *escapingUse = walker.getEscapingUse()) { |
| 508 | + llvm::errs() << " escapes at:\n"; |
| 509 | + escapingUse->getUser()->printInContext(llvm::errs()); |
| 510 | + } |
| 511 | + ASSERT(false && "caller must check for pointer escapes"); |
| 512 | + } |
498 | 513 | return endLifetimeAtBoundary(scopedAddress.value, liveness, boundary, |
499 | 514 | deadEndBlocks); |
500 | 515 | } |
@@ -524,6 +539,15 @@ bool OSSALifetimeCompletion::analyzeAndUpdateLifetime(SILValue value, |
524 | 539 | } |
525 | 540 | InteriorLiveness liveness(value); |
526 | 541 | liveness.compute(domInfo, handleInnerScope); |
| 542 | + if (VerifyLifetimeCompletion && boundary != Boundary::Availability |
| 543 | + && liveness.getAddressUseKind() != AddressUseKind::NonEscaping) { |
| 544 | + llvm::errs() << "Incomplete liveness for: " << value; |
| 545 | + if (auto *escapingUse = liveness.escapingUse) { |
| 546 | + llvm::errs() << " escapes at:\n"; |
| 547 | + escapingUse->getUser()->printInContext(llvm::errs()); |
| 548 | + } |
| 549 | + ASSERT(false && "caller must check for pointer escapes"); |
| 550 | + } |
527 | 551 | return endLifetimeAtBoundary(value, liveness.getLiveness(), boundary, |
528 | 552 | deadEndBlocks); |
529 | 553 | } |
|
0 commit comments