From 11ba91f321a65a2cd02cb925f72ffdf9291eabfd Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sat, 16 May 2015 15:40:03 +0000 Subject: [PATCH] [WinEH] Push unique_ptr through the Action interface. This was the source of many leaks in the past, this should fix them once and for all. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237524 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/WinEHFuncInfo.h | 3 +- .../SelectionDAG/FunctionLoweringInfo.cpp | 36 ++++++++----------- lib/CodeGen/WinEHPrepare.cpp | 34 +++++++++--------- 3 files changed, 33 insertions(+), 40 deletions(-) diff --git a/include/llvm/CodeGen/WinEHFuncInfo.h b/include/llvm/CodeGen/WinEHFuncInfo.h index 6a9b82f9518..4efdfdf912e 100644 --- a/include/llvm/CodeGen/WinEHFuncInfo.h +++ b/include/llvm/CodeGen/WinEHFuncInfo.h @@ -107,8 +107,7 @@ public: }; void parseEHActions(const IntrinsicInst *II, - SmallVectorImpl &Actions); - + SmallVectorImpl> &Actions); // The following structs respresent the .xdata for functions using C++ // exceptions on Windows. diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index 21a00583bf0..4819a6e2d79 100644 --- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -89,7 +89,7 @@ struct WinEHNumbering { int CurrentBaseState; int NextState; - SmallVector HandlerStack; + SmallVector, 4> HandlerStack; SmallPtrSet VisitedHandlers; int currentEHNumber() const { @@ -99,7 +99,8 @@ struct WinEHNumbering { void createUnwindMapEntry(int ToState, ActionHandler *AH); void createTryBlockMapEntry(int TryLow, int TryHigh, ArrayRef Handlers); - void processCallSite(ArrayRef Actions, ImmutableCallSite CS); + void processCallSite(MutableArrayRef> Actions, + ImmutableCallSite CS); void calculateStateNumbers(const Function &F); }; } @@ -324,13 +325,13 @@ void FunctionLoweringInfo::addSEHHandlersForLPads( // Parse the llvm.eh.actions call we found. MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()]; - SmallVector Actions; + SmallVector, 4> Actions; parseEHActions(ActionsCall, Actions); // Iterate EH actions from most to least precedence, which means // iterating in reverse. for (auto I = Actions.rbegin(), E = Actions.rend(); I != E; ++I) { - ActionHandler *Action = *I; + ActionHandler *Action = I->get(); if (auto *CH = dyn_cast(Action)) { const auto *Filter = dyn_cast(CH->getSelector()->stripPointerCasts()); @@ -345,7 +346,6 @@ void FunctionLoweringInfo::addSEHHandlersForLPads( MMI.addSEHCleanupHandler(LPadMBB, Fini); } } - DeleteContainerPointers(Actions); } } @@ -401,8 +401,9 @@ static void print_name(const Value *V) { #endif } -void WinEHNumbering::processCallSite(ArrayRef Actions, - ImmutableCallSite CS) { +void WinEHNumbering::processCallSite( + MutableArrayRef> Actions, + ImmutableCallSite CS) { DEBUG(dbgs() << "processCallSite (EH state = " << currentEHNumber() << ") for: "); print_name(CS ? CS.getCalledValue() : nullptr); @@ -426,21 +427,15 @@ void WinEHNumbering::processCallSite(ArrayRef Actions, if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() != Actions[FirstMismatch]->getHandlerBlockOrFunc()) break; - // Delete any actions that are already represented on the handler stack. - delete Actions[FirstMismatch]; } // Don't recurse while we are looping over the handler stack. Instead, defer // the numbering of the catch handlers until we are done popping. SmallVector PoppedCatches; for (int I = HandlerStack.size() - 1; I >= FirstMismatch; --I) { - if (auto *CH = dyn_cast(HandlerStack.back())) { - PoppedCatches.push_back(CH); - } else { - // Delete cleanup handlers - delete HandlerStack.back(); - } - HandlerStack.pop_back(); + std::unique_ptr Handler = HandlerStack.pop_back_val(); + if (isa(Handler.get())) + PoppedCatches.push_back(cast(Handler.release())); } int TryHigh = NextState - 1; @@ -487,7 +482,6 @@ void WinEHNumbering::processCallSite(ArrayRef Actions, if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() != Actions[FirstMismatch]->getHandlerBlockOrFunc()) break; - delete Actions[FirstMismatch]; } } @@ -498,7 +492,7 @@ void WinEHNumbering::processCallSite(ArrayRef Actions, bool LastActionWasCatch = false; for (size_t I = FirstMismatch; I != Actions.size(); ++I) { // We can reuse eh states when pushing two catches for the same invoke. - bool CurrActionIsCatch = isa(Actions[I]); + bool CurrActionIsCatch = isa(Actions[I].get()); // FIXME: Reenable this optimization! if (CurrActionIsCatch && LastActionWasCatch && false) { DEBUG(dbgs() << "setEHState for handler to " << currentEHNumber() @@ -508,12 +502,12 @@ void WinEHNumbering::processCallSite(ArrayRef Actions, DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber() << ", "); print_name(Actions[I]->getHandlerBlockOrFunc()); DEBUG(dbgs() << ")\n"); - createUnwindMapEntry(currentEHNumber(), Actions[I]); + createUnwindMapEntry(currentEHNumber(), Actions[I].get()); DEBUG(dbgs() << "setEHState for handler to " << NextState << "\n"); Actions[I]->setEHState(NextState); NextState++; } - HandlerStack.push_back(Actions[I]); + HandlerStack.push_back(std::move(Actions[I])); LastActionWasCatch = CurrActionIsCatch; } @@ -533,7 +527,7 @@ void WinEHNumbering::calculateStateNumbers(const Function &F) { } DEBUG(dbgs() << "Calculating state numbers for: " << F.getName() << '\n'); - SmallVector ActionList; + SmallVector, 4> ActionList; for (const BasicBlock &BB : F) { for (const Instruction &I : BB) { const auto *CI = dyn_cast(&I); diff --git a/lib/CodeGen/WinEHPrepare.cpp b/lib/CodeGen/WinEHPrepare.cpp index 2cebb1d40cf..482385a0667 100644 --- a/lib/CodeGen/WinEHPrepare.cpp +++ b/lib/CodeGen/WinEHPrepare.cpp @@ -867,22 +867,21 @@ bool WinEHPrepare::prepareExceptionHandlers( // Populate the indirectbr instructions' target lists if we deferred // doing so above. SetVector CheckedTargets; + SmallVector, 4> ActionList; for (auto &LPadImplPair : LPadImpls) { IntrinsicInst *Recover = cast(LPadImplPair.first); IndirectBrInst *Branch = LPadImplPair.second; // Get a list of handlers called by - SmallVector ActionList; parseEHActions(Recover, ActionList); // Add an indirect branch listing possible successors of the catch handlers. SetVector ReturnTargets; - for (ActionHandler *Action : ActionList) { - if (auto *CA = dyn_cast(Action)) { + for (const auto &Action : ActionList) { + if (auto *CA = dyn_cast(Action.get())) { Function *Handler = cast(CA->getHandlerBlockOrFunc()); getPossibleReturnTargets(&F, Handler, ReturnTargets); } - delete Action; } ActionList.clear(); for (BasicBlock *Target : ReturnTargets) { @@ -1045,10 +1044,10 @@ void WinEHPrepare::getPossibleReturnTargets(Function *ParentF, // parent function. if (auto *LPI = BB.getLandingPadInst()) { IntrinsicInst *Recover = cast(LPI->getNextNode()); - SmallVector ActionList; + SmallVector, 4> ActionList; parseEHActions(Recover, ActionList); - for (auto *Action : ActionList) { - if (auto *CH = dyn_cast(Action)) { + for (const auto &Action : ActionList) { + if (auto *CH = dyn_cast(Action.get())) { Function *NestedF = cast(CH->getHandlerBlockOrFunc()); getPossibleReturnTargets(ParentF, NestedF, Targets); } @@ -1101,10 +1100,10 @@ void WinEHPrepare::completeNestedLandingPad(Function *ParentFn, // Remap the exception variables into the outlined function. SmallVector ActionTargets; - SmallVector ActionList; + SmallVector, 4> ActionList; parseEHActions(EHActions, ActionList); - for (auto *Action : ActionList) { - auto *Catch = dyn_cast(Action); + for (const auto &Action : ActionList) { + auto *Catch = dyn_cast(Action.get()); if (!Catch) continue; // The dyn_cast to function here selects C++ catch handlers and skips @@ -1142,7 +1141,6 @@ void WinEHPrepare::completeNestedLandingPad(Function *ParentFn, ActionTargets.push_back(NewBA); } } - DeleteContainerPointers(ActionList); ActionList.clear(); OutlinedBB->getInstList().push_back(EHActions); @@ -2322,8 +2320,9 @@ void WinEHPrepare::findCleanupHandlers(LandingPadActions &Actions, // This is a public function, declared in WinEHFuncInfo.h and is also // referenced by WinEHNumbering in FunctionLoweringInfo.cpp. -void llvm::parseEHActions(const IntrinsicInst *II, - SmallVectorImpl &Actions) { +void llvm::parseEHActions( + const IntrinsicInst *II, + SmallVectorImpl> &Actions) { for (unsigned I = 0, E = II->getNumArgOperands(); I != E;) { uint64_t ActionKind = cast(II->getArgOperand(I))->getZExtValue(); @@ -2333,16 +2332,17 @@ void llvm::parseEHActions(const IntrinsicInst *II, int64_t EHObjIndexVal = EHObjIndex->getSExtValue(); Constant *Handler = cast(II->getArgOperand(I + 3)); I += 4; - auto *CH = new CatchHandler(/*BB=*/nullptr, Selector, /*NextBB=*/nullptr); + auto CH = make_unique(/*BB=*/nullptr, Selector, + /*NextBB=*/nullptr); CH->setHandlerBlockOrFunc(Handler); CH->setExceptionVarIndex(EHObjIndexVal); - Actions.push_back(CH); + Actions.push_back(std::move(CH)); } else if (ActionKind == 0) { Constant *Handler = cast(II->getArgOperand(I + 1)); I += 2; - auto *CH = new CleanupHandler(/*BB=*/nullptr); + auto CH = make_unique(/*BB=*/nullptr); CH->setHandlerBlockOrFunc(Handler); - Actions.push_back(CH); + Actions.push_back(std::move(CH)); } else { llvm_unreachable("Expected either a catch or cleanup handler!"); } -- 2.34.1