@@ -62,6 +62,7 @@ SILFunction *GenericCloner::createDeclaration(
62
62
void GenericCloner::populateCloned () {
63
63
assert (AllocStacks.empty () && " Stale cloner state." );
64
64
assert (!ReturnValueAddr && " Stale cloner state." );
65
+ assert (!ErrorValueAddr && " Stale cloner state." );
65
66
66
67
SILFunction *Cloned = getCloned ();
67
68
// Create arguments for the entry block.
@@ -95,17 +96,33 @@ void GenericCloner::populateCloned() {
95
96
return false ;
96
97
97
98
if (ArgIdx < origConv.getSILArgIndexOfFirstParam ()) {
98
- // Handle result arguments.
99
- unsigned formalIdx =
100
- origConv.getIndirectFormalResultIndexForSILArg (ArgIdx);
101
- if (ReInfo.isFormalResultConverted (formalIdx)) {
102
- // This result is converted from indirect to direct. The return inst
103
- // needs to load the value from the alloc_stack. See below.
104
- createAllocStack ();
105
- assert (!ReturnValueAddr);
106
- ReturnValueAddr = ASI;
107
- entryArgs.push_back (ASI);
108
- return true ;
99
+ if (ArgIdx < origConv.getNumIndirectSILResults ()) {
100
+ // Handle result arguments.
101
+ unsigned formalIdx =
102
+ origConv.getIndirectFormalResultIndexForSILArg (ArgIdx);
103
+ if (ReInfo.isFormalResultConverted (formalIdx)) {
104
+ // This result is converted from indirect to direct. The return inst
105
+ // needs to load the value from the alloc_stack. See below.
106
+ createAllocStack ();
107
+ assert (!ReturnValueAddr);
108
+ ReturnValueAddr = ASI;
109
+ entryArgs.push_back (ASI);
110
+ return true ;
111
+ }
112
+ } else {
113
+ assert (origConv.getNumIndirectSILErrorResults () == 1 &&
114
+ " only a single indirect error result is supported" );
115
+ assert (ArgIdx == origConv.getNumIndirectSILResults ());
116
+
117
+ if (ReInfo.isErrorResultConverted ()) {
118
+ // This error result is converted from indirect to direct. The throw
119
+ // instruction needs to load the value from the alloc_stack. See below.
120
+ createAllocStack ();
121
+ assert (!ErrorValueAddr);
122
+ ErrorValueAddr = ASI;
123
+ entryArgs.push_back (ASI);
124
+ return true ;
125
+ }
109
126
}
110
127
} else if (ReInfo.isDroppedMetatypeArg (ArgIdx)) {
111
128
// Replace the metatype argument with an `metatype` instruction in the
@@ -195,6 +212,17 @@ void GenericCloner::visitTerminator(SILBasicBlock *BB) {
195
212
getBuilder ().createReturn (RI->getLoc (), ReturnValue);
196
213
return ;
197
214
}
215
+ } else if (isa<ThrowAddrInst>(OrigTermInst) && ErrorValueAddr) {
216
+ // The result is converted from indirect to direct. We have to load the
217
+ // returned value from the alloc_stack.
218
+ SILValue errorValue = getBuilder ().emitLoadValueOperation (
219
+ ErrorValueAddr->getLoc (), ErrorValueAddr,
220
+ LoadOwnershipQualifier::Take);
221
+ for (AllocStackInst *ASI : reverse (AllocStacks)) {
222
+ getBuilder ().createDeallocStack (ASI->getLoc (), ASI);
223
+ }
224
+ getBuilder ().createThrow (OrigTermInst->getLoc (), errorValue);
225
+ return ;
198
226
} else if (OrigTermInst->isFunctionExiting ()) {
199
227
for (AllocStackInst *ASI : reverse (AllocStacks)) {
200
228
getBuilder ().createDeallocStack (ASI->getLoc (), ASI);
0 commit comments