Skip to content

Commit d7466e5

Browse files
committed
IRGen: Fix DenseMap interior pointer invalidation bug in IRGenSILFunction::visitEndApply.
Fixes rdar://144216380.
1 parent a619daf commit d7466e5

File tree

2 files changed

+38
-33
lines changed

2 files changed

+38
-33
lines changed

lib/IRGen/IRGenSIL.cpp

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4764,42 +4764,49 @@ void IRGenSILFunction::visitAbortApplyInst(AbortApplyInst *i) {
47644764
}
47654765

47664766
void IRGenSILFunction::visitEndApply(BeginApplyInst *i, EndApplyInst *ei) {
4767-
const auto &coroutine = getLoweredCoroutine(i->getTokenResult());
4768-
bool isAbort = ei == nullptr;
4769-
4770-
auto sig = Signature::forCoroutineContinuation(IGM, i->getOrigCalleeType());
4771-
4772-
// Cast the continuation pointer to the right function pointer type.
4773-
auto continuation = coroutine.Continuation;
4774-
continuation = Builder.CreateBitCast(continuation,
4775-
sig.getType()->getPointerTo());
4776-
4777-
auto schemaAndEntity =
4778-
getCoroutineResumeFunctionPointerAuth(IGM, i->getOrigCalleeType());
4779-
auto pointerAuth = PointerAuthInfo::emit(*this, schemaAndEntity.first,
4780-
coroutine.Buffer.getAddress(),
4781-
schemaAndEntity.second);
4782-
auto callee = FunctionPointer::createSigned(i->getOrigCalleeType(),
4783-
continuation, pointerAuth, sig);
4784-
4785-
auto *call = Builder.CreateCall(callee, {
4786-
coroutine.Buffer.getAddress(),
4787-
llvm::ConstantInt::get(IGM.Int1Ty, isAbort)
4788-
});
4767+
{
4768+
const auto &coroutine = getLoweredCoroutine(i->getTokenResult());
4769+
bool isAbort = ei == nullptr;
4770+
4771+
auto sig = Signature::forCoroutineContinuation(IGM, i->getOrigCalleeType());
4772+
4773+
// Cast the continuation pointer to the right function pointer type.
4774+
auto continuation = coroutine.Continuation;
4775+
continuation = Builder.CreateBitCast(continuation,
4776+
sig.getType()->getPointerTo());
4777+
4778+
auto schemaAndEntity =
4779+
getCoroutineResumeFunctionPointerAuth(IGM, i->getOrigCalleeType());
4780+
auto pointerAuth = PointerAuthInfo::emit(*this, schemaAndEntity.first,
4781+
coroutine.Buffer.getAddress(),
4782+
schemaAndEntity.second);
4783+
auto callee = FunctionPointer::createSigned(i->getOrigCalleeType(),
4784+
continuation, pointerAuth, sig);
4785+
4786+
auto *call = Builder.CreateCall(callee, {
4787+
coroutine.Buffer.getAddress(),
4788+
llvm::ConstantInt::get(IGM.Int1Ty, isAbort)
4789+
});
47894790

4790-
if (!isAbort) {
4791-
auto resultType = call->getType();
4792-
if (!resultType->isVoidTy()) {
4793-
Explosion e;
4794-
// FIXME: Do we need to handle ABI-related conversions here?
4795-
// It seems we cannot have C function convention for coroutines, etc.
4796-
extractScalarResults(*this, resultType, call, e);
4797-
setLoweredExplosion(ei, e);
4791+
if (!isAbort) {
4792+
auto resultType = call->getType();
4793+
if (!resultType->isVoidTy()) {
4794+
Explosion e;
4795+
// FIXME: Do we need to handle ABI-related conversions here?
4796+
// It seems we cannot have C function convention for coroutines, etc.
4797+
extractScalarResults(*this, resultType, call, e);
4798+
4799+
// NOTE: This inserts a new entry into the LoweredValues DenseMap,
4800+
// invalidating the reference held by `coroutine` in this scope.
4801+
setLoweredExplosion(ei, e);
4802+
}
47984803
}
47994804
}
48004805

4806+
// Re-fetch the coroutine state from its new location in the DenseMap after
4807+
// the invalidation above.
4808+
const auto &coroutine = getLoweredCoroutine(i->getTokenResult());
48014809
coroutine.Temporaries.destroyAll(*this);
4802-
48034810
emitDeallocYieldOnceCoroutineBuffer(*this, coroutine.Buffer);
48044811
}
48054812

test/AutoDiff/validation-test/modify_accessor.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// REQUIRES: rdar144216380
2-
31
// RUN: %target-run-simple-swift
42
// REQUIRES: executable_test
53

0 commit comments

Comments
 (0)