@@ -2664,6 +2664,29 @@ RValue RValueEmitter::visitUnreachableExpr(UnreachableExpr *E, SGFContext C) {
26642664 return RValue (SGF, E, ManagedValue::forRValueWithoutOwnership (undef));
26652665}
26662666
2667+ static SILValue getArrayBuffer (SILValue array, SILGenFunction &SGF, SILLocation loc) {
2668+ SILValue v = array;
2669+ SILType storageType;
2670+ while (auto *sd = v->getType ().getStructOrBoundGenericStruct ()) {
2671+ ASSERT (sd->getStoredProperties ().size () == 1 &&
2672+ " Array or its internal structs should have exactly one stored property" );
2673+ auto *se = SGF.getBuilder ().createStructExtract (loc, v, v->getType ().getFieldDecl (0 ));
2674+ if (se->getType () == SILType::getBridgeObjectType (SGF.getASTContext ())) {
2675+ auto bridgeObjTy = cast<BoundGenericStructType>(v->getType ().getASTType ());
2676+ CanType ct = CanType (bridgeObjTy->getGenericArgs ()[0 ]);
2677+ storageType = SILType::getPrimitiveObjectType (ct);
2678+ }
2679+ v = se;
2680+ }
2681+
2682+ if (storageType) {
2683+ v = SGF.getBuilder ().createUncheckedRefCast (loc, v, storageType);
2684+ }
2685+ ASSERT (v->getType ().isReferenceCounted (&SGF.F ) &&
2686+ " expected a reference-counted buffer in the Array data type" );
2687+ return v;
2688+ }
2689+
26672690VarargsInfo Lowering::emitBeginVarargs (SILGenFunction &SGF, SILLocation loc,
26682691 CanType baseTy, CanType arrayTy,
26692692 unsigned numElements) {
@@ -2675,12 +2698,7 @@ VarargsInfo Lowering::emitBeginVarargs(SILGenFunction &SGF, SILLocation loc,
26752698 SILValue numEltsVal = SGF.B .createIntegerLiteral (loc,
26762699 SILType::getBuiltinWordType (SGF.getASTContext ()),
26772700 numElements);
2678- // The first result is the array value.
2679- ManagedValue array;
2680- // The second result is a RawPointer to the base address of the array.
2681- SILValue basePtr;
2682- std::tie (array, basePtr)
2683- = SGF.emitUninitializedArrayAllocation (arrayTy, numEltsVal, loc);
2701+ ManagedValue array = SGF.emitUninitializedArrayAllocation (arrayTy, numEltsVal, loc);
26842702
26852703 // Temporarily deactivate the main array cleanup.
26862704 if (array.hasCleanup ())
@@ -2690,13 +2708,15 @@ VarargsInfo Lowering::emitBeginVarargs(SILGenFunction &SGF, SILLocation loc,
26902708 auto abortCleanup =
26912709 SGF.enterDeallocateUninitializedArrayCleanup (array.getValue ());
26922710
2693- // Turn the pointer into an address.
2694- basePtr = SGF.B .createPointerToAddress (
2695- loc, basePtr, baseTL.getLoweredType ().getAddressType (),
2696- /* isStrict*/ true ,
2697- /* isInvariant*/ false );
2711+ auto borrowedArray = array.borrow (SGF, loc);
2712+ auto borrowCleanup = SGF.Cleanups .getTopCleanup ();
2713+
2714+ SILValue buffer = getArrayBuffer (borrowedArray.getValue (), SGF, loc);
26982715
2699- return VarargsInfo (array, abortCleanup, basePtr, baseTL, baseAbstraction);
2716+ SILType elementAddrTy = baseTL.getLoweredType ().getAddressType ();
2717+ SILValue baseAddr = SGF.getBuilder ().createRefTailAddr (loc, buffer, elementAddrTy);
2718+
2719+ return VarargsInfo (array, borrowCleanup, abortCleanup, baseAddr, baseTL, baseAbstraction);
27002720}
27012721
27022722ManagedValue Lowering::emitEndVarargs (SILGenFunction &SGF, SILLocation loc,
@@ -2710,6 +2730,8 @@ ManagedValue Lowering::emitEndVarargs(SILGenFunction &SGF, SILLocation loc,
27102730 if (array.hasCleanup ())
27112731 SGF.Cleanups .setCleanupState (array.getCleanup (), CleanupState::Active);
27122732
2733+ SGF.Cleanups .popAndEmitCleanup (varargs.getBorrowCleanup (), CleanupLocation (loc), NotForUnwind);
2734+
27132735 // Array literals only need to be finalized, if the array is really allocated.
27142736 // In case of zero elements, no allocation is done, but the empty-array
27152737 // singleton is used. "Finalization" means to emit an end_cow_mutation
0 commit comments