llvm.org GIT mirror llvm / 11ba91f
[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 Benjamin Kramer 5 years ago
3 changed file(s) with 33 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
106106 };
107107
108108 void parseEHActions(const IntrinsicInst *II,
109 SmallVectorImpl &Actions);
110
109 SmallVectorImpl> &Actions);
111110
112111 // The following structs respresent the .xdata for functions using C++
113112 // exceptions on Windows.
8888 int CurrentBaseState;
8989 int NextState;
9090
91 SmallVector<ActionHandler *, 4> HandlerStack;
91 SmallVector<std::unique_ptr, 4> HandlerStack;
9292 SmallPtrSet VisitedHandlers;
9393
9494 int currentEHNumber() const {
9898 void createUnwindMapEntry(int ToState, ActionHandler *AH);
9999 void createTryBlockMapEntry(int TryLow, int TryHigh,
100100 ArrayRef Handlers);
101 void processCallSite(ArrayRef Actions, ImmutableCallSite CS);
101 void processCallSite(MutableArrayRef> Actions,
102 ImmutableCallSite CS);
102103 void calculateStateNumbers(const Function &F);
103104 };
104105 }
323324
324325 // Parse the llvm.eh.actions call we found.
325326 MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()];
326 SmallVector<ActionHandler *, 4> Actions;
327 SmallVector<std::unique_ptr, 4> Actions;
327328 parseEHActions(ActionsCall, Actions);
328329
329330 // Iterate EH actions from most to least precedence, which means
330331 // iterating in reverse.
331332 for (auto I = Actions.rbegin(), E = Actions.rend(); I != E; ++I) {
332 ActionHandler *Action = *I;
333 ActionHandler *Action = I->get();
333334 if (auto *CH = dyn_cast(Action)) {
334335 const auto *Filter =
335336 dyn_cast(CH->getSelector()->stripPointerCasts());
344345 MMI.addSEHCleanupHandler(LPadMBB, Fini);
345346 }
346347 }
347 DeleteContainerPointers(Actions);
348348 }
349349 }
350350
400400 #endif
401401 }
402402
403 void WinEHNumbering::processCallSite(ArrayRef Actions,
404 ImmutableCallSite CS) {
403 void WinEHNumbering::processCallSite(
404 MutableArrayRef> Actions,
405 ImmutableCallSite CS) {
405406 DEBUG(dbgs() << "processCallSite (EH state = " << currentEHNumber()
406407 << ") for: ");
407408 print_name(CS ? CS.getCalledValue() : nullptr);
425426 if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() !=
426427 Actions[FirstMismatch]->getHandlerBlockOrFunc())
427428 break;
428 // Delete any actions that are already represented on the handler stack.
429 delete Actions[FirstMismatch];
430429 }
431430
432431 // Don't recurse while we are looping over the handler stack. Instead, defer
433432 // the numbering of the catch handlers until we are done popping.
434433 SmallVector PoppedCatches;
435434 for (int I = HandlerStack.size() - 1; I >= FirstMismatch; --I) {
436 if (auto *CH = dyn_cast(HandlerStack.back())) {
437 PoppedCatches.push_back(CH);
438 } else {
439 // Delete cleanup handlers
440 delete HandlerStack.back();
441 }
442 HandlerStack.pop_back();
435 std::unique_ptr Handler = HandlerStack.pop_back_val();
436 if (isa(Handler.get()))
437 PoppedCatches.push_back(cast(Handler.release()));
443438 }
444439
445440 int TryHigh = NextState - 1;
486481 if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() !=
487482 Actions[FirstMismatch]->getHandlerBlockOrFunc())
488483 break;
489 delete Actions[FirstMismatch];
490484 }
491485 }
492486
497491 bool LastActionWasCatch = false;
498492 for (size_t I = FirstMismatch; I != Actions.size(); ++I) {
499493 // We can reuse eh states when pushing two catches for the same invoke.
500 bool CurrActionIsCatch = isa(Actions[I]);
494 bool CurrActionIsCatch = isa(Actions[I].get());
501495 // FIXME: Reenable this optimization!
502496 if (CurrActionIsCatch && LastActionWasCatch && false) {
503497 DEBUG(dbgs() << "setEHState for handler to " << currentEHNumber()
507501 DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber() << ", ");
508502 print_name(Actions[I]->getHandlerBlockOrFunc());
509503 DEBUG(dbgs() << ")\n");
510 createUnwindMapEntry(currentEHNumber(), Actions[I]);
504 createUnwindMapEntry(currentEHNumber(), Actions[I].get());
511505 DEBUG(dbgs() << "setEHState for handler to " << NextState << "\n");
512506 Actions[I]->setEHState(NextState);
513507 NextState++;
514508 }
515 HandlerStack.push_back(Actions[I]);
509 HandlerStack.push_back(std::move(Actions[I]));
516510 LastActionWasCatch = CurrActionIsCatch;
517511 }
518512
532526 }
533527
534528 DEBUG(dbgs() << "Calculating state numbers for: " << F.getName() << '\n');
535 SmallVector<ActionHandler *, 4> ActionList;
529 SmallVector<std::unique_ptr, 4> ActionList;
536530 for (const BasicBlock &BB : F) {
537531 for (const Instruction &I : BB) {
538532 const auto *CI = dyn_cast(&I);
866866 // Populate the indirectbr instructions' target lists if we deferred
867867 // doing so above.
868868 SetVector CheckedTargets;
869 SmallVector, 4> ActionList;
869870 for (auto &LPadImplPair : LPadImpls) {
870871 IntrinsicInst *Recover = cast(LPadImplPair.first);
871872 IndirectBrInst *Branch = LPadImplPair.second;
872873
873874 // Get a list of handlers called by
874 SmallVector ActionList;
875875 parseEHActions(Recover, ActionList);
876876
877877 // Add an indirect branch listing possible successors of the catch handlers.
878878 SetVector ReturnTargets;
879 for (ActionHandler *Action : ActionList) {
880 if (auto *CA = dyn_cast(Action)) {
879 for (const auto &Action : ActionList) {
880 if (auto *CA = dyn_cast(Action.get())) {
881881 Function *Handler = cast(CA->getHandlerBlockOrFunc());
882882 getPossibleReturnTargets(&F, Handler, ReturnTargets);
883883 }
884 delete Action;
885884 }
886885 ActionList.clear();
887886 for (BasicBlock *Target : ReturnTargets) {
10441043 // parent function.
10451044 if (auto *LPI = BB.getLandingPadInst()) {
10461045 IntrinsicInst *Recover = cast(LPI->getNextNode());
1047 SmallVector<ActionHandler *, 4> ActionList;
1046 SmallVector<std::unique_ptr, 4> ActionList;
10481047 parseEHActions(Recover, ActionList);
1049 for (auto *Action : ActionList) {
1050 if (auto *CH = dyn_cast(Action)) {
1048 for (const auto &Action : ActionList) {
1049 if (auto *CH = dyn_cast(Action.get())) {
10511050 Function *NestedF = cast(CH->getHandlerBlockOrFunc());
10521051 getPossibleReturnTargets(ParentF, NestedF, Targets);
10531052 }
11001099
11011100 // Remap the exception variables into the outlined function.
11021101 SmallVector ActionTargets;
1103 SmallVector<ActionHandler *, 4> ActionList;
1102 SmallVector<std::unique_ptr, 4> ActionList;
11041103 parseEHActions(EHActions, ActionList);
1105 for (auto *Action : ActionList) {
1106 auto *Catch = dyn_cast(Action);
1104 for (const auto &Action : ActionList) {
1105 auto *Catch = dyn_cast(Action.get());
11071106 if (!Catch)
11081107 continue;
11091108 // The dyn_cast to function here selects C++ catch handlers and skips
11411140 ActionTargets.push_back(NewBA);
11421141 }
11431142 }
1144 DeleteContainerPointers(ActionList);
11451143 ActionList.clear();
11461144 OutlinedBB->getInstList().push_back(EHActions);
11471145
23212319
23222320 // This is a public function, declared in WinEHFuncInfo.h and is also
23232321 // referenced by WinEHNumbering in FunctionLoweringInfo.cpp.
2324 void llvm::parseEHActions(const IntrinsicInst *II,
2325 SmallVectorImpl &Actions) {
2322 void llvm::parseEHActions(
2323 const IntrinsicInst *II,
2324 SmallVectorImpl> &Actions) {
23262325 for (unsigned I = 0, E = II->getNumArgOperands(); I != E;) {
23272326 uint64_t ActionKind =
23282327 cast(II->getArgOperand(I))->getZExtValue();
23322331 int64_t EHObjIndexVal = EHObjIndex->getSExtValue();
23332332 Constant *Handler = cast(II->getArgOperand(I + 3));
23342333 I += 4;
2335 auto *CH = new CatchHandler(/*BB=*/nullptr, Selector, /*NextBB=*/nullptr);
2334 auto CH = make_unique(/*BB=*/nullptr, Selector,
2335 /*NextBB=*/nullptr);
23362336 CH->setHandlerBlockOrFunc(Handler);
23372337 CH->setExceptionVarIndex(EHObjIndexVal);
2338 Actions.push_back(CH);
2338 Actions.push_back(std::move(CH));
23392339 } else if (ActionKind == 0) {
23402340 Constant *Handler = cast(II->getArgOperand(I + 1));
23412341 I += 2;
2342 auto *CH = new CleanupHandler(/*BB=*/nullptr);
2342 auto CH = make_unique(/*BB=*/nullptr);
23432343 CH->setHandlerBlockOrFunc(Handler);
2344 Actions.push_back(CH);
2344 Actions.push_back(std::move(CH));
23452345 } else {
23462346 llvm_unreachable("Expected either a catch or cleanup handler!");
23472347 }