Skip to content

Commit 00ecc6c

Browse files
committed
SILGen: fix typed throws emission for opaque values
We use a direct @error emission style when opaque values is enabled, relying on AddressLowering to satisfy the formal @error_indirect convention.
1 parent b9f0578 commit 00ecc6c

File tree

3 files changed

+30
-24
lines changed

3 files changed

+30
-24
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2089,10 +2089,17 @@ static void emitRawApply(SILGenFunction &SGF,
20892089
auto result = normalBB->createPhiArgument(resultType, OwnershipKind::Owned);
20902090
rawResults.push_back(result);
20912091

2092+
// If the error is not passed indirectly, include the expected error type
2093+
// according to the SILFunctionConvention.
2094+
std::optional<TaggedUnion<SILValue, SILType>> errorAddrOrType;
2095+
if (indirectErrorAddr)
2096+
errorAddrOrType = indirectErrorAddr;
2097+
else
2098+
errorAddrOrType = substFnConv.getSILErrorType(SGF.getTypeExpansionContext());
2099+
20922100
SILBasicBlock *errorBB =
20932101
SGF.getTryApplyErrorDest(loc, substFnType, prevExecutor,
2094-
substFnType->getErrorResult(),
2095-
indirectErrorAddr,
2102+
*errorAddrOrType,
20962103
options.contains(ApplyFlags::DoesNotThrow));
20972104

20982105
options -= ApplyFlags::DoesNotThrow;
@@ -5962,9 +5969,9 @@ RValue SILGenFunction::emitApply(
59625969

59635970
SILValue indirectErrorAddr;
59645971
if (substFnType->hasErrorResult()) {
5965-
auto errorResult = substFnType->getErrorResult();
5966-
if (errorResult.getConvention() == ResultConvention::Indirect) {
5967-
auto loweredErrorResultType = getSILType(errorResult, substFnType);
5972+
auto convention = silConv.getFunctionConventions(substFnType);
5973+
if (auto errorResult = convention.getIndirectErrorResult()) {
5974+
auto loweredErrorResultType = getSILType(*errorResult, substFnType);
59685975
indirectErrorAddr = B.createAllocStack(loc, loweredErrorResultType);
59695976
enterDeallocStackCleanup(indirectErrorAddr);
59705977
}

lib/SILGen/SILGenFunction.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2388,9 +2388,8 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
23882388
SILBasicBlock *getTryApplyErrorDest(SILLocation loc,
23892389
CanSILFunctionType fnTy,
23902390
ExecutorBreadcrumb prevExecutor,
2391-
SILResultInfo errorResult,
2392-
SILValue indirectErrorAddr,
2393-
bool isSuppressed);
2391+
TaggedUnion<SILValue, SILType> errorAddrOrType,
2392+
bool suppressErrorPath);
23942393

23952394
/// Emit a dynamic member reference.
23962395
RValue emitDynamicMemberRef(SILLocation loc, SILValue operand,

lib/SILGen/SILGenStmt.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,23 +1564,29 @@ void StmtEmitter::visitFailStmt(FailStmt *S) {
15641564

15651565
/// Return a basic block suitable to be the destination block of a
15661566
/// try_apply instruction. The block is implicitly emitted and filled in.
1567+
///
1568+
/// \param errorAddrOrType Either the address of the indirect error result where
1569+
/// the result will be stored, or the type of the expected Owned error value.
1570+
///
1571+
/// \param suppressErrorPath Should the error path be emitted as unreachable?
15671572
SILBasicBlock *
15681573
SILGenFunction::getTryApplyErrorDest(SILLocation loc,
15691574
CanSILFunctionType fnTy,
15701575
ExecutorBreadcrumb prevExecutor,
1571-
SILResultInfo errorResult,
1572-
SILValue indirectErrorAddr,
1576+
TaggedUnion<SILValue, SILType> errorAddrOrType,
15731577
bool suppressErrorPath) {
15741578
// For now, don't try to re-use destination blocks for multiple
15751579
// failure sites.
15761580
SILBasicBlock *destBB = createBasicBlock(FunctionSection::Postmatter);
15771581

15781582
SILValue errorValue;
1579-
if (errorResult.getConvention() == ResultConvention::Owned) {
1580-
errorValue = destBB->createPhiArgument(getSILType(errorResult, fnTy),
1581-
OwnershipKind::Owned);
1583+
if (auto ownedErrorTy = errorAddrOrType.dyn_cast<SILType>()) {
1584+
errorValue = destBB->createPhiArgument(*ownedErrorTy,
1585+
OwnershipKind::Owned);
15821586
} else {
1583-
errorValue = indirectErrorAddr;
1587+
auto errorAddr = errorAddrOrType.get<SILValue>();
1588+
assert(errorAddr->getType().isAddress());
1589+
errorValue = errorAddr;
15841590
}
15851591

15861592
assert(B.hasValidInsertionPoint() && B.insertingAtEndOfBlock());
@@ -1653,9 +1659,6 @@ void SILGenFunction::emitThrow(SILLocation loc, ManagedValue exnMV,
16531659
} else {
16541660
// Call the _willThrowTyped entrypoint, which handles
16551661
// arbitrary error types.
1656-
SILValue tmpBuffer;
1657-
SILValue error;
1658-
16591662
FuncDecl *entrypoint = ctx.getWillThrowTyped();
16601663
auto genericSig = entrypoint->getGenericSignature();
16611664
SubstitutionMap subMap = SubstitutionMap::get(
@@ -1668,18 +1671,15 @@ void SILGenFunction::emitThrow(SILLocation loc, ManagedValue exnMV,
16681671
// Materialize the error so we can pass the address down to the
16691672
// swift_willThrowTyped.
16701673
exnMV = exnMV.materialize(*this, loc);
1671-
error = exnMV.getValue();
1672-
exn = exnMV.forward(*this);
1673-
} else {
1674-
// Claim the exception value.
1675-
exn = exnMV.forward(*this);
1676-
error = exn;
16771674
}
16781675

16791676
emitApplyOfLibraryIntrinsic(
16801677
loc, entrypoint, subMap,
1681-
{ ManagedValue::forForwardedRValue(*this, error) },
1678+
{ exnMV },
16821679
SGFContext());
1680+
1681+
// Claim the exception value.
1682+
exn = exnMV.forward(*this);
16831683
}
16841684
} else {
16851685
// Claim the exception value.

0 commit comments

Comments
 (0)