/// Set up epilogue work for the thunk arguments based in the given argument. /// Default implementation simply passes it through. void FunctionSignatureTransform:: OwnedToGuaranteedAddArgumentRelease(ArgumentDescriptor &AD, SILBuilder &Builder, SILFunction *F) { // If we have any arguments that were consumed but are now guaranteed, // insert a release_value. if (!AD.OwnedToGuaranteed) { return; } SILInstruction *Call = findOnlyApply(F); if (isa<ApplyInst>(Call)) { Builder.setInsertionPoint(&*std::next(SILBasicBlock::iterator(Call))); Builder.createReleaseValue(RegularLocation(SourceLoc()), F->getArguments()[AD.Index], Builder.getDefaultAtomicity()); } else { SILBasicBlock *NormalBB = dyn_cast<TryApplyInst>(Call)->getNormalBB(); Builder.setInsertionPoint(&*NormalBB->begin()); Builder.createReleaseValue(RegularLocation(SourceLoc()), F->getArguments()[AD.Index], Builder.getDefaultAtomicity()); SILBasicBlock *ErrorBB = dyn_cast<TryApplyInst>(Call)->getErrorBB(); Builder.setInsertionPoint(&*ErrorBB->begin()); Builder.createReleaseValue(RegularLocation(SourceLoc()), F->getArguments()[AD.Index], Builder.getDefaultAtomicity()); } }
/// Checks whether any of the arguments to the apply are closures and diagnoses /// if any of the @inout_aliasable captures passed to those closures have /// in-progress accesses that would conflict with any access the summary /// says the closure would perform. // /// TODO: We currently fail to statically diagnose non-escaping closures pased /// via @block_storage convention. To enforce this case, we should statically /// recognize when the apply takes a block argument that has been initialized to /// a non-escaping closure. static void checkForViolationsInNoEscapeClosures( const StorageMap &Accesses, FullApplySite FAS, AccessSummaryAnalysis *ASA, llvm::SmallVectorImpl<ConflictingAccess> &ConflictingAccesses) { SILFunction *Callee = FAS.getCalleeFunction(); if (Callee && !Callee->empty()) { // Check for violation with directly called closure checkForViolationWithCall(Accesses, Callee, 0, FAS.getArguments(), ASA, ConflictingAccesses); } // Check for violation with closures passed as arguments for (SILValue Argument : FAS.getArguments()) { auto *PAI = lookThroughForPartialApply(Argument); if (!PAI) continue; SILFunction *Closure = PAI->getCalleeFunction(); if (!Closure || Closure->empty()) continue; // Check the closure's captures, which are a suffix of the closure's // parameters. unsigned StartIndex = Closure->getArguments().size() - PAI->getNumCallArguments(); checkForViolationWithCall(Accesses, Closure, StartIndex, PAI->getArguments(), ASA, ConflictingAccesses); } }