@@ -62,6 +62,7 @@ SILFunction *GenericCloner::createDeclaration(
6262void GenericCloner::populateCloned () {
6363 assert (AllocStacks.empty () && " Stale cloner state." );
6464 assert (!ReturnValueAddr && " Stale cloner state." );
65+ assert (!ErrorValueAddr && " Stale cloner state." );
6566
6667 SILFunction *Cloned = getCloned ();
6768 // Create arguments for the entry block.
@@ -95,17 +96,33 @@ void GenericCloner::populateCloned() {
9596 return false ;
9697
9798 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+ }
109126 }
110127 } else if (ReInfo.isDroppedMetatypeArg (ArgIdx)) {
111128 // Replace the metatype argument with an `metatype` instruction in the
@@ -192,10 +209,20 @@ void GenericCloner::visitTerminator(SILBasicBlock *BB) {
192209 getBuilder ().createDeallocStack (ASI->getLoc (), ASI);
193210 }
194211 if (ReturnValue) {
195- auto *NewReturn = getBuilder ().createReturn (RI->getLoc (), ReturnValue);
196- FunctionExits.push_back (NewReturn);
212+ getBuilder ().createReturn (RI->getLoc (), ReturnValue);
197213 return ;
198214 }
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 ;
199226 } else if (OrigTermInst->isFunctionExiting ()) {
200227 for (AllocStackInst *ASI : reverse (AllocStacks)) {
201228 getBuilder ().createDeallocStack (ASI->getLoc (), ASI);
0 commit comments