From 787839120885519d4cbff64ad59e179bdf3744fa Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 10 Sep 2015 00:25:23 +0000 Subject: [WinEH] Add codegen support for cleanuppad and cleanupret All of the complexity is in cleanupret, and it mostly follows the same codepaths as catchret, except it doesn't take a return value in RAX. This small example now compiles and executes successfully on win32: extern "C" int printf(const char *, ...) noexcept; struct Dtor { ~Dtor() { printf("~Dtor\n"); } }; void has_cleanup() { Dtor o; throw 42; } int main() { try { has_cleanup(); } catch (int) { printf("caught it\n"); } } Don't try to put the cleanup in the same function as the catch, or Bad Things will happen. llvm-svn: 247219 --- .../CodeGen/SelectionDAG/FunctionLoweringInfo.cpp | 35 +++++++++++----------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp') diff --git a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index 15793f666ea..fe359777a36 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -223,8 +223,6 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, assert(&*BB->begin() == I && "WinEHPrepare failed to remove PHIs from imaginary BBs"); continue; - } else if (!isa(I)) { - llvm_unreachable("unhandled EH pad in MBB graph"); } } @@ -269,7 +267,7 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, SmallVector LPads; for (BB = Fn->begin(); BB != EB; ++BB) { const Instruction *FNP = BB->getFirstNonPHI(); - if (BB->isEHPad() && !isa(FNP) && !isa(FNP)) + if (BB->isEHPad() && MBBMap.count(BB)) MBBMap[BB]->setIsEHPad(); if (const auto *LPI = dyn_cast(FNP)) LPads.push_back(LPI); @@ -289,24 +287,27 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, // Calculate state numbers if we haven't already. WinEHFuncInfo &EHInfo = MMI.getWinEHFuncInfo(&fn); - if (Personality == EHPersonality::MSVC_CXX) { - const Function *WinEHParentFn = MMI.getWinEHParent(&fn); + const Function *WinEHParentFn = MMI.getWinEHParent(&fn); + if (Personality == EHPersonality::MSVC_CXX) calculateWinCXXEHStateNumbers(WinEHParentFn, EHInfo); - } else { - const Function *WinEHParentFn = MMI.getWinEHParent(&fn); + else calculateSEHStateNumbers(WinEHParentFn, EHInfo); + + // Map all BB references in the WinEH data to MBBs. + for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) + for (WinEHHandlerType &H : TBME.HandlerArray) + if (const auto *BB = + dyn_cast(H.Handler.get())) + H.Handler = MBBMap[BB]; + for (WinEHUnwindMapEntry &UME : EHInfo.UnwindMap) + if (UME.Cleanup) + if (const auto *BB = dyn_cast(UME.Cleanup.get())) + UME.Cleanup = MBBMap[BB]; + for (SEHUnwindMapEntry &UME : EHInfo.SEHUnwindMap) { + const BasicBlock *BB = UME.Handler.get(); + UME.Handler = MBBMap[BB]; } - // Map all BB references in the EH data to MBBs. - for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) - for (WinEHHandlerType &H : TBME.HandlerArray) - if (const auto *BB = - dyn_cast(H.Handler.get())) - H.Handler = MBBMap[BB]; - for (SEHUnwindMapEntry &UME : EHInfo.SEHUnwindMap) { - const BasicBlock *BB = UME.Handler.get(); - UME.Handler = MBBMap[BB]; - } // If there's an explicit EH registration node on the stack, record its // frame index. if (EHInfo.EHRegNode && EHInfo.EHRegNode->getParent()->getParent() == Fn) { -- cgit v1.2.3