Skip to content

Commit fa11bdf

Browse files
committed
RawSILInstLowering: delete an unused partial_apply when lowering assign_by_wrapper
So far we left this cleanup to SILCombine. But the unused partial_apply (i.e. the "set" in case it's an init or the "init" in case it's a set) violates memory lifetime rules in case "self" is an inout. Once we verify that, it would result in a memory lifetime violation.
1 parent d26b1f0 commit fa11bdf

File tree

1 file changed

+6
-4
lines changed

1 file changed

+6
-4
lines changed

lib/SILOptimizer/Mandatory/RawSILInstLowering.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "swift/SIL/SILInstruction.h"
1717
#include "swift/SILOptimizer/PassManager/Passes.h"
1818
#include "swift/SILOptimizer/PassManager/Transforms.h"
19+
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
1920
#include "llvm/ADT/Statistic.h"
2021

2122
STATISTIC(numAssignRewritten, "Number of assigns rewritten");
@@ -177,6 +178,7 @@ static void lowerAssignByWrapperInstruction(SILBuilderWithScope &b,
177178
SILValue dest = inst->getDest();
178179
SILLocation loc = inst->getLoc();
179180
SILBuilderWithScope forCleanup(std::next(inst->getIterator()));
181+
SingleValueInstruction *closureToDelete = nullptr;
180182

181183
switch (inst->getAssignDestination()) {
182184
case AssignByWrapperInst::Destination::BackingWrapper: {
@@ -199,8 +201,7 @@ static void lowerAssignByWrapperInstruction(SILBuilderWithScope &b,
199201
b.createStore(loc, wrappedSrc, dest, StoreOwnershipQualifier::Assign);
200202
}
201203
}
202-
// TODO: remove the unused setter function, which usually is a dead
203-
// partial_apply.
204+
closureToDelete = dyn_cast<SingleValueInstruction>(inst->getSetter());
204205
break;
205206
}
206207
case AssignByWrapperInst::Destination::WrappedValue: {
@@ -218,12 +219,13 @@ static void lowerAssignByWrapperInstruction(SILBuilderWithScope &b,
218219
// nested access violation.
219220
if (auto *BA = dyn_cast<BeginAccessInst>(dest))
220221
accessMarkers.push_back(BA);
221-
// TODO: remove the unused init function, which usually is a dead
222-
// partial_apply.
222+
closureToDelete = dyn_cast<SingleValueInstruction>(inst->getInitializer());
223223
break;
224224
}
225225
}
226226
inst->eraseFromParent();
227+
if (closureToDelete)
228+
tryDeleteDeadClosure(closureToDelete);
227229
}
228230

229231
static void deleteDeadAccessMarker(BeginAccessInst *BA) {

0 commit comments

Comments
 (0)