[llvm] r237524 - [WinEH] Push unique_ptr through the Action interface.

Benjamin Kramer benny.kra at googlemail.com
Sat May 16 08:40:03 PDT 2015


Author: d0k
Date: Sat May 16 10:40:03 2015
New Revision: 237524

URL: http://llvm.org/viewvc/llvm-project?rev=237524&view=rev
Log:
[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.

Modified:
    llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h
    llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
    llvm/trunk/lib/CodeGen/WinEHPrepare.cpp

Modified: llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h?rev=237524&r1=237523&r2=237524&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h Sat May 16 10:40:03 2015
@@ -107,8 +107,7 @@ public:
 };
 
 void parseEHActions(const IntrinsicInst *II,
-  SmallVectorImpl<ActionHandler *> &Actions);
-
+                    SmallVectorImpl<std::unique_ptr<ActionHandler>> &Actions);
 
 // The following structs respresent the .xdata for functions using C++
 // exceptions on Windows.

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp?rev=237524&r1=237523&r2=237524&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp Sat May 16 10:40:03 2015
@@ -89,7 +89,7 @@ struct WinEHNumbering {
   int CurrentBaseState;
   int NextState;
 
-  SmallVector<ActionHandler *, 4> HandlerStack;
+  SmallVector<std::unique_ptr<ActionHandler>, 4> HandlerStack;
   SmallPtrSet<const Function *, 4> VisitedHandlers;
 
   int currentEHNumber() const {
@@ -99,7 +99,8 @@ struct WinEHNumbering {
   void createUnwindMapEntry(int ToState, ActionHandler *AH);
   void createTryBlockMapEntry(int TryLow, int TryHigh,
                               ArrayRef<CatchHandler *> Handlers);
-  void processCallSite(ArrayRef<ActionHandler *> Actions, ImmutableCallSite CS);
+  void processCallSite(MutableArrayRef<std::unique_ptr<ActionHandler>> Actions,
+                       ImmutableCallSite CS);
   void calculateStateNumbers(const Function &F);
 };
 }
@@ -324,13 +325,13 @@ void FunctionLoweringInfo::addSEHHandler
 
     // Parse the llvm.eh.actions call we found.
     MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()];
-    SmallVector<ActionHandler *, 4> Actions;
+    SmallVector<std::unique_ptr<ActionHandler>, 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<CatchHandler>(Action)) {
         const auto *Filter =
             dyn_cast<Function>(CH->getSelector()->stripPointerCasts());
@@ -345,7 +346,6 @@ void FunctionLoweringInfo::addSEHHandler
         MMI.addSEHCleanupHandler(LPadMBB, Fini);
       }
     }
-    DeleteContainerPointers(Actions);
   }
 }
 
@@ -401,8 +401,9 @@ static void print_name(const Value *V) {
 #endif
 }
 
-void WinEHNumbering::processCallSite(ArrayRef<ActionHandler *> Actions,
-                                     ImmutableCallSite CS) {
+void WinEHNumbering::processCallSite(
+    MutableArrayRef<std::unique_ptr<ActionHandler>> Actions,
+    ImmutableCallSite CS) {
   DEBUG(dbgs() << "processCallSite (EH state = " << currentEHNumber()
                << ") for: ");
   print_name(CS ? CS.getCalledValue() : nullptr);
@@ -426,21 +427,15 @@ void WinEHNumbering::processCallSite(Arr
     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<CatchHandler *, 4> PoppedCatches;
   for (int I = HandlerStack.size() - 1; I >= FirstMismatch; --I) {
-    if (auto *CH = dyn_cast<CatchHandler>(HandlerStack.back())) {
-      PoppedCatches.push_back(CH);
-    } else {
-      // Delete cleanup handlers
-      delete HandlerStack.back();
-    }
-    HandlerStack.pop_back();
+    std::unique_ptr<ActionHandler> Handler = HandlerStack.pop_back_val();
+    if (isa<CatchHandler>(Handler.get()))
+      PoppedCatches.push_back(cast<CatchHandler>(Handler.release()));
   }
 
   int TryHigh = NextState - 1;
@@ -487,7 +482,6 @@ void WinEHNumbering::processCallSite(Arr
       if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() !=
           Actions[FirstMismatch]->getHandlerBlockOrFunc())
         break;
-      delete Actions[FirstMismatch];
     }
   }
 
@@ -498,7 +492,7 @@ void WinEHNumbering::processCallSite(Arr
   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<CatchHandler>(Actions[I]);
+    bool CurrActionIsCatch = isa<CatchHandler>(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(Arr
       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::calculateStateNumbe
   }
 
   DEBUG(dbgs() << "Calculating state numbers for: " << F.getName() << '\n');
-  SmallVector<ActionHandler *, 4> ActionList;
+  SmallVector<std::unique_ptr<ActionHandler>, 4> ActionList;
   for (const BasicBlock &BB : F) {
     for (const Instruction &I : BB) {
       const auto *CI = dyn_cast<CallInst>(&I);

Modified: llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/WinEHPrepare.cpp?rev=237524&r1=237523&r2=237524&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/WinEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/WinEHPrepare.cpp Sat May 16 10:40:03 2015
@@ -867,22 +867,21 @@ bool WinEHPrepare::prepareExceptionHandl
   // Populate the indirectbr instructions' target lists if we deferred
   // doing so above.
   SetVector<BasicBlock*> CheckedTargets;
+  SmallVector<std::unique_ptr<ActionHandler>, 4> ActionList;
   for (auto &LPadImplPair : LPadImpls) {
     IntrinsicInst *Recover = cast<IntrinsicInst>(LPadImplPair.first);
     IndirectBrInst *Branch = LPadImplPair.second;
 
     // Get a list of handlers called by 
-    SmallVector<ActionHandler *, 4> ActionList;
     parseEHActions(Recover, ActionList);
 
     // Add an indirect branch listing possible successors of the catch handlers.
     SetVector<BasicBlock *> ReturnTargets;
-    for (ActionHandler *Action : ActionList) {
-      if (auto *CA = dyn_cast<CatchHandler>(Action)) {
+    for (const auto &Action : ActionList) {
+      if (auto *CA = dyn_cast<CatchHandler>(Action.get())) {
         Function *Handler = cast<Function>(CA->getHandlerBlockOrFunc());
         getPossibleReturnTargets(&F, Handler, ReturnTargets);
       }
-      delete Action;
     }
     ActionList.clear();
     for (BasicBlock *Target : ReturnTargets) {
@@ -1045,10 +1044,10 @@ void WinEHPrepare::getPossibleReturnTarg
     // parent function.
     if (auto *LPI = BB.getLandingPadInst()) {
       IntrinsicInst *Recover = cast<IntrinsicInst>(LPI->getNextNode());
-      SmallVector<ActionHandler *, 4> ActionList;
+      SmallVector<std::unique_ptr<ActionHandler>, 4> ActionList;
       parseEHActions(Recover, ActionList);
-      for (auto *Action : ActionList) {
-        if (auto *CH = dyn_cast<CatchHandler>(Action)) {
+      for (const auto &Action : ActionList) {
+        if (auto *CH = dyn_cast<CatchHandler>(Action.get())) {
           Function *NestedF = cast<Function>(CH->getHandlerBlockOrFunc());
           getPossibleReturnTargets(ParentF, NestedF, Targets);
         }
@@ -1101,10 +1100,10 @@ void WinEHPrepare::completeNestedLanding
 
   // Remap the exception variables into the outlined function.
   SmallVector<BlockAddress *, 4> ActionTargets;
-  SmallVector<ActionHandler *, 4> ActionList;
+  SmallVector<std::unique_ptr<ActionHandler>, 4> ActionList;
   parseEHActions(EHActions, ActionList);
-  for (auto *Action : ActionList) {
-    auto *Catch = dyn_cast<CatchHandler>(Action);
+  for (const auto &Action : ActionList) {
+    auto *Catch = dyn_cast<CatchHandler>(Action.get());
     if (!Catch)
       continue;
     // The dyn_cast to function here selects C++ catch handlers and skips
@@ -1142,7 +1141,6 @@ void WinEHPrepare::completeNestedLanding
       ActionTargets.push_back(NewBA);
     }
   }
-  DeleteContainerPointers(ActionList);
   ActionList.clear();
   OutlinedBB->getInstList().push_back(EHActions);
 
@@ -2322,8 +2320,9 @@ void WinEHPrepare::findCleanupHandlers(L
 
 // 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<ActionHandler *> &Actions) {
+void llvm::parseEHActions(
+    const IntrinsicInst *II,
+    SmallVectorImpl<std::unique_ptr<ActionHandler>> &Actions) {
   for (unsigned I = 0, E = II->getNumArgOperands(); I != E;) {
     uint64_t ActionKind =
         cast<ConstantInt>(II->getArgOperand(I))->getZExtValue();
@@ -2333,16 +2332,17 @@ void llvm::parseEHActions(const Intrinsi
       int64_t EHObjIndexVal = EHObjIndex->getSExtValue();
       Constant *Handler = cast<Constant>(II->getArgOperand(I + 3));
       I += 4;
-      auto *CH = new CatchHandler(/*BB=*/nullptr, Selector, /*NextBB=*/nullptr);
+      auto CH = make_unique<CatchHandler>(/*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<Constant>(II->getArgOperand(I + 1));
       I += 2;
-      auto *CH = new CleanupHandler(/*BB=*/nullptr);
+      auto CH = make_unique<CleanupHandler>(/*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!");
     }





More information about the llvm-commits mailing list