diff options
author | Reid Kleckner <rnk@google.com> | 2015-09-10 00:25:23 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2015-09-10 00:25:23 +0000 |
commit | 787839120885519d4cbff64ad59e179bdf3744fa (patch) | |
tree | dd894b990329961d9452bd1f672fe38c263c7100 /llvm/lib/CodeGen/AsmPrinter/WinException.cpp | |
parent | 60f3e1f466c9dfa834ab9e71ae4fe0589a42774f (diff) | |
download | bcm5719-llvm-787839120885519d4cbff64ad59e179bdf3744fa.tar.gz bcm5719-llvm-787839120885519d4cbff64ad59e179bdf3744fa.zip |
[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
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/WinException.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/WinException.cpp | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp index e706d73dee2..095315809cb 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -316,10 +316,11 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) { /// Retreive the MCSymbol for a GlobalValue or MachineBasicBlock. GlobalValues /// are used in the old WinEH scheme, and they will be removed eventually. static MCSymbol *getMCSymbolForMBBOrGV(AsmPrinter *Asm, ValueOrMBB Handler) { + if (!Handler) + return nullptr; if (Handler.is<MachineBasicBlock *>()) return Handler.get<MachineBasicBlock *>()->getSymbol(); - else - return Asm->getSymbol(cast<GlobalValue>(Handler.get<const Value *>())); + return Asm->getSymbol(cast<GlobalValue>(Handler.get<const Value *>())); } void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { @@ -404,8 +405,9 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { if (UnwindMapXData) { OS.EmitLabel(UnwindMapXData); for (const WinEHUnwindMapEntry &UME : FuncInfo.UnwindMap) { - OS.EmitIntValue(UME.ToState, 4); // ToState - OS.EmitValue(create32bitRef(UME.Cleanup), 4); // Action + MCSymbol *CleanupSym = getMCSymbolForMBBOrGV(Asm, UME.Cleanup); + OS.EmitIntValue(UME.ToState, 4); // ToState + OS.EmitValue(create32bitRef(CleanupSym), 4); // Action } } |