mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-14 14:24:05 +00:00
[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
This commit is contained in:
@ -107,8 +107,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void parseEHActions(const IntrinsicInst *II,
|
void parseEHActions(const IntrinsicInst *II,
|
||||||
SmallVectorImpl<ActionHandler *> &Actions);
|
SmallVectorImpl<std::unique_ptr<ActionHandler>> &Actions);
|
||||||
|
|
||||||
|
|
||||||
// The following structs respresent the .xdata for functions using C++
|
// The following structs respresent the .xdata for functions using C++
|
||||||
// exceptions on Windows.
|
// exceptions on Windows.
|
||||||
|
@ -89,7 +89,7 @@ struct WinEHNumbering {
|
|||||||
int CurrentBaseState;
|
int CurrentBaseState;
|
||||||
int NextState;
|
int NextState;
|
||||||
|
|
||||||
SmallVector<ActionHandler *, 4> HandlerStack;
|
SmallVector<std::unique_ptr<ActionHandler>, 4> HandlerStack;
|
||||||
SmallPtrSet<const Function *, 4> VisitedHandlers;
|
SmallPtrSet<const Function *, 4> VisitedHandlers;
|
||||||
|
|
||||||
int currentEHNumber() const {
|
int currentEHNumber() const {
|
||||||
@ -99,7 +99,8 @@ struct WinEHNumbering {
|
|||||||
void createUnwindMapEntry(int ToState, ActionHandler *AH);
|
void createUnwindMapEntry(int ToState, ActionHandler *AH);
|
||||||
void createTryBlockMapEntry(int TryLow, int TryHigh,
|
void createTryBlockMapEntry(int TryLow, int TryHigh,
|
||||||
ArrayRef<CatchHandler *> Handlers);
|
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);
|
void calculateStateNumbers(const Function &F);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -324,13 +325,13 @@ void FunctionLoweringInfo::addSEHHandlersForLPads(
|
|||||||
|
|
||||||
// Parse the llvm.eh.actions call we found.
|
// Parse the llvm.eh.actions call we found.
|
||||||
MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()];
|
MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()];
|
||||||
SmallVector<ActionHandler *, 4> Actions;
|
SmallVector<std::unique_ptr<ActionHandler>, 4> Actions;
|
||||||
parseEHActions(ActionsCall, Actions);
|
parseEHActions(ActionsCall, Actions);
|
||||||
|
|
||||||
// Iterate EH actions from most to least precedence, which means
|
// Iterate EH actions from most to least precedence, which means
|
||||||
// iterating in reverse.
|
// iterating in reverse.
|
||||||
for (auto I = Actions.rbegin(), E = Actions.rend(); I != E; ++I) {
|
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)) {
|
if (auto *CH = dyn_cast<CatchHandler>(Action)) {
|
||||||
const auto *Filter =
|
const auto *Filter =
|
||||||
dyn_cast<Function>(CH->getSelector()->stripPointerCasts());
|
dyn_cast<Function>(CH->getSelector()->stripPointerCasts());
|
||||||
@ -345,7 +346,6 @@ void FunctionLoweringInfo::addSEHHandlersForLPads(
|
|||||||
MMI.addSEHCleanupHandler(LPadMBB, Fini);
|
MMI.addSEHCleanupHandler(LPadMBB, Fini);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DeleteContainerPointers(Actions);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,7 +401,8 @@ static void print_name(const Value *V) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinEHNumbering::processCallSite(ArrayRef<ActionHandler *> Actions,
|
void WinEHNumbering::processCallSite(
|
||||||
|
MutableArrayRef<std::unique_ptr<ActionHandler>> Actions,
|
||||||
ImmutableCallSite CS) {
|
ImmutableCallSite CS) {
|
||||||
DEBUG(dbgs() << "processCallSite (EH state = " << currentEHNumber()
|
DEBUG(dbgs() << "processCallSite (EH state = " << currentEHNumber()
|
||||||
<< ") for: ");
|
<< ") for: ");
|
||||||
@ -426,21 +427,15 @@ void WinEHNumbering::processCallSite(ArrayRef<ActionHandler *> Actions,
|
|||||||
if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() !=
|
if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() !=
|
||||||
Actions[FirstMismatch]->getHandlerBlockOrFunc())
|
Actions[FirstMismatch]->getHandlerBlockOrFunc())
|
||||||
break;
|
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
|
// Don't recurse while we are looping over the handler stack. Instead, defer
|
||||||
// the numbering of the catch handlers until we are done popping.
|
// the numbering of the catch handlers until we are done popping.
|
||||||
SmallVector<CatchHandler *, 4> PoppedCatches;
|
SmallVector<CatchHandler *, 4> PoppedCatches;
|
||||||
for (int I = HandlerStack.size() - 1; I >= FirstMismatch; --I) {
|
for (int I = HandlerStack.size() - 1; I >= FirstMismatch; --I) {
|
||||||
if (auto *CH = dyn_cast<CatchHandler>(HandlerStack.back())) {
|
std::unique_ptr<ActionHandler> Handler = HandlerStack.pop_back_val();
|
||||||
PoppedCatches.push_back(CH);
|
if (isa<CatchHandler>(Handler.get()))
|
||||||
} else {
|
PoppedCatches.push_back(cast<CatchHandler>(Handler.release()));
|
||||||
// Delete cleanup handlers
|
|
||||||
delete HandlerStack.back();
|
|
||||||
}
|
|
||||||
HandlerStack.pop_back();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int TryHigh = NextState - 1;
|
int TryHigh = NextState - 1;
|
||||||
@ -487,7 +482,6 @@ void WinEHNumbering::processCallSite(ArrayRef<ActionHandler *> Actions,
|
|||||||
if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() !=
|
if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() !=
|
||||||
Actions[FirstMismatch]->getHandlerBlockOrFunc())
|
Actions[FirstMismatch]->getHandlerBlockOrFunc())
|
||||||
break;
|
break;
|
||||||
delete Actions[FirstMismatch];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,7 +492,7 @@ void WinEHNumbering::processCallSite(ArrayRef<ActionHandler *> Actions,
|
|||||||
bool LastActionWasCatch = false;
|
bool LastActionWasCatch = false;
|
||||||
for (size_t I = FirstMismatch; I != Actions.size(); ++I) {
|
for (size_t I = FirstMismatch; I != Actions.size(); ++I) {
|
||||||
// We can reuse eh states when pushing two catches for the same invoke.
|
// 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!
|
// FIXME: Reenable this optimization!
|
||||||
if (CurrActionIsCatch && LastActionWasCatch && false) {
|
if (CurrActionIsCatch && LastActionWasCatch && false) {
|
||||||
DEBUG(dbgs() << "setEHState for handler to " << currentEHNumber()
|
DEBUG(dbgs() << "setEHState for handler to " << currentEHNumber()
|
||||||
@ -508,12 +502,12 @@ void WinEHNumbering::processCallSite(ArrayRef<ActionHandler *> Actions,
|
|||||||
DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber() << ", ");
|
DEBUG(dbgs() << "createUnwindMapEntry(" << currentEHNumber() << ", ");
|
||||||
print_name(Actions[I]->getHandlerBlockOrFunc());
|
print_name(Actions[I]->getHandlerBlockOrFunc());
|
||||||
DEBUG(dbgs() << ")\n");
|
DEBUG(dbgs() << ")\n");
|
||||||
createUnwindMapEntry(currentEHNumber(), Actions[I]);
|
createUnwindMapEntry(currentEHNumber(), Actions[I].get());
|
||||||
DEBUG(dbgs() << "setEHState for handler to " << NextState << "\n");
|
DEBUG(dbgs() << "setEHState for handler to " << NextState << "\n");
|
||||||
Actions[I]->setEHState(NextState);
|
Actions[I]->setEHState(NextState);
|
||||||
NextState++;
|
NextState++;
|
||||||
}
|
}
|
||||||
HandlerStack.push_back(Actions[I]);
|
HandlerStack.push_back(std::move(Actions[I]));
|
||||||
LastActionWasCatch = CurrActionIsCatch;
|
LastActionWasCatch = CurrActionIsCatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -533,7 +527,7 @@ void WinEHNumbering::calculateStateNumbers(const Function &F) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(dbgs() << "Calculating state numbers for: " << F.getName() << '\n');
|
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 BasicBlock &BB : F) {
|
||||||
for (const Instruction &I : BB) {
|
for (const Instruction &I : BB) {
|
||||||
const auto *CI = dyn_cast<CallInst>(&I);
|
const auto *CI = dyn_cast<CallInst>(&I);
|
||||||
|
@ -867,22 +867,21 @@ bool WinEHPrepare::prepareExceptionHandlers(
|
|||||||
// Populate the indirectbr instructions' target lists if we deferred
|
// Populate the indirectbr instructions' target lists if we deferred
|
||||||
// doing so above.
|
// doing so above.
|
||||||
SetVector<BasicBlock*> CheckedTargets;
|
SetVector<BasicBlock*> CheckedTargets;
|
||||||
|
SmallVector<std::unique_ptr<ActionHandler>, 4> ActionList;
|
||||||
for (auto &LPadImplPair : LPadImpls) {
|
for (auto &LPadImplPair : LPadImpls) {
|
||||||
IntrinsicInst *Recover = cast<IntrinsicInst>(LPadImplPair.first);
|
IntrinsicInst *Recover = cast<IntrinsicInst>(LPadImplPair.first);
|
||||||
IndirectBrInst *Branch = LPadImplPair.second;
|
IndirectBrInst *Branch = LPadImplPair.second;
|
||||||
|
|
||||||
// Get a list of handlers called by
|
// Get a list of handlers called by
|
||||||
SmallVector<ActionHandler *, 4> ActionList;
|
|
||||||
parseEHActions(Recover, ActionList);
|
parseEHActions(Recover, ActionList);
|
||||||
|
|
||||||
// Add an indirect branch listing possible successors of the catch handlers.
|
// Add an indirect branch listing possible successors of the catch handlers.
|
||||||
SetVector<BasicBlock *> ReturnTargets;
|
SetVector<BasicBlock *> ReturnTargets;
|
||||||
for (ActionHandler *Action : ActionList) {
|
for (const auto &Action : ActionList) {
|
||||||
if (auto *CA = dyn_cast<CatchHandler>(Action)) {
|
if (auto *CA = dyn_cast<CatchHandler>(Action.get())) {
|
||||||
Function *Handler = cast<Function>(CA->getHandlerBlockOrFunc());
|
Function *Handler = cast<Function>(CA->getHandlerBlockOrFunc());
|
||||||
getPossibleReturnTargets(&F, Handler, ReturnTargets);
|
getPossibleReturnTargets(&F, Handler, ReturnTargets);
|
||||||
}
|
}
|
||||||
delete Action;
|
|
||||||
}
|
}
|
||||||
ActionList.clear();
|
ActionList.clear();
|
||||||
for (BasicBlock *Target : ReturnTargets) {
|
for (BasicBlock *Target : ReturnTargets) {
|
||||||
@ -1045,10 +1044,10 @@ void WinEHPrepare::getPossibleReturnTargets(Function *ParentF,
|
|||||||
// parent function.
|
// parent function.
|
||||||
if (auto *LPI = BB.getLandingPadInst()) {
|
if (auto *LPI = BB.getLandingPadInst()) {
|
||||||
IntrinsicInst *Recover = cast<IntrinsicInst>(LPI->getNextNode());
|
IntrinsicInst *Recover = cast<IntrinsicInst>(LPI->getNextNode());
|
||||||
SmallVector<ActionHandler *, 4> ActionList;
|
SmallVector<std::unique_ptr<ActionHandler>, 4> ActionList;
|
||||||
parseEHActions(Recover, ActionList);
|
parseEHActions(Recover, ActionList);
|
||||||
for (auto *Action : ActionList) {
|
for (const auto &Action : ActionList) {
|
||||||
if (auto *CH = dyn_cast<CatchHandler>(Action)) {
|
if (auto *CH = dyn_cast<CatchHandler>(Action.get())) {
|
||||||
Function *NestedF = cast<Function>(CH->getHandlerBlockOrFunc());
|
Function *NestedF = cast<Function>(CH->getHandlerBlockOrFunc());
|
||||||
getPossibleReturnTargets(ParentF, NestedF, Targets);
|
getPossibleReturnTargets(ParentF, NestedF, Targets);
|
||||||
}
|
}
|
||||||
@ -1101,10 +1100,10 @@ void WinEHPrepare::completeNestedLandingPad(Function *ParentFn,
|
|||||||
|
|
||||||
// Remap the exception variables into the outlined function.
|
// Remap the exception variables into the outlined function.
|
||||||
SmallVector<BlockAddress *, 4> ActionTargets;
|
SmallVector<BlockAddress *, 4> ActionTargets;
|
||||||
SmallVector<ActionHandler *, 4> ActionList;
|
SmallVector<std::unique_ptr<ActionHandler>, 4> ActionList;
|
||||||
parseEHActions(EHActions, ActionList);
|
parseEHActions(EHActions, ActionList);
|
||||||
for (auto *Action : ActionList) {
|
for (const auto &Action : ActionList) {
|
||||||
auto *Catch = dyn_cast<CatchHandler>(Action);
|
auto *Catch = dyn_cast<CatchHandler>(Action.get());
|
||||||
if (!Catch)
|
if (!Catch)
|
||||||
continue;
|
continue;
|
||||||
// The dyn_cast to function here selects C++ catch handlers and skips
|
// 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);
|
ActionTargets.push_back(NewBA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DeleteContainerPointers(ActionList);
|
|
||||||
ActionList.clear();
|
ActionList.clear();
|
||||||
OutlinedBB->getInstList().push_back(EHActions);
|
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
|
// This is a public function, declared in WinEHFuncInfo.h and is also
|
||||||
// referenced by WinEHNumbering in FunctionLoweringInfo.cpp.
|
// referenced by WinEHNumbering in FunctionLoweringInfo.cpp.
|
||||||
void llvm::parseEHActions(const IntrinsicInst *II,
|
void llvm::parseEHActions(
|
||||||
SmallVectorImpl<ActionHandler *> &Actions) {
|
const IntrinsicInst *II,
|
||||||
|
SmallVectorImpl<std::unique_ptr<ActionHandler>> &Actions) {
|
||||||
for (unsigned I = 0, E = II->getNumArgOperands(); I != E;) {
|
for (unsigned I = 0, E = II->getNumArgOperands(); I != E;) {
|
||||||
uint64_t ActionKind =
|
uint64_t ActionKind =
|
||||||
cast<ConstantInt>(II->getArgOperand(I))->getZExtValue();
|
cast<ConstantInt>(II->getArgOperand(I))->getZExtValue();
|
||||||
@ -2333,16 +2332,17 @@ void llvm::parseEHActions(const IntrinsicInst *II,
|
|||||||
int64_t EHObjIndexVal = EHObjIndex->getSExtValue();
|
int64_t EHObjIndexVal = EHObjIndex->getSExtValue();
|
||||||
Constant *Handler = cast<Constant>(II->getArgOperand(I + 3));
|
Constant *Handler = cast<Constant>(II->getArgOperand(I + 3));
|
||||||
I += 4;
|
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->setHandlerBlockOrFunc(Handler);
|
||||||
CH->setExceptionVarIndex(EHObjIndexVal);
|
CH->setExceptionVarIndex(EHObjIndexVal);
|
||||||
Actions.push_back(CH);
|
Actions.push_back(std::move(CH));
|
||||||
} else if (ActionKind == 0) {
|
} else if (ActionKind == 0) {
|
||||||
Constant *Handler = cast<Constant>(II->getArgOperand(I + 1));
|
Constant *Handler = cast<Constant>(II->getArgOperand(I + 1));
|
||||||
I += 2;
|
I += 2;
|
||||||
auto *CH = new CleanupHandler(/*BB=*/nullptr);
|
auto CH = make_unique<CleanupHandler>(/*BB=*/nullptr);
|
||||||
CH->setHandlerBlockOrFunc(Handler);
|
CH->setHandlerBlockOrFunc(Handler);
|
||||||
Actions.push_back(CH);
|
Actions.push_back(std::move(CH));
|
||||||
} else {
|
} else {
|
||||||
llvm_unreachable("Expected either a catch or cleanup handler!");
|
llvm_unreachable("Expected either a catch or cleanup handler!");
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user