diff options
author | Bob Wilson <bob.wilson@apple.com> | 2011-11-16 07:12:00 +0000 |
---|---|---|
committer | Bob Wilson <bob.wilson@apple.com> | 2011-11-16 07:12:00 +0000 |
commit | 20c918dfed5830f6d0c54c9c38817bd660cb6a13 (patch) | |
tree | 824466449ac7fd1262f53f97dbc3d49f777ed6e6 | |
parent | eaab6ef6eb12fc950f1d4371b297d9b7ca9d4c66 (diff) | |
download | external_llvm-20c918dfed5830f6d0c54c9c38817bd660cb6a13.zip external_llvm-20c918dfed5830f6d0c54c9c38817bd660cb6a13.tar.gz external_llvm-20c918dfed5830f6d0c54c9c38817bd660cb6a13.tar.bz2 |
Update the SP in the SjLj jmpbuf whenever it changes. <rdar://problem/10444602>
This same basic code was in the older version of the SjLj exception handling,
but it was removed in the recent revisions to that code. It needs to be there.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@144782 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/SjLjEHPrepare.cpp | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/lib/CodeGen/SjLjEHPrepare.cpp b/lib/CodeGen/SjLjEHPrepare.cpp index ac88441..5d60bc9 100644 --- a/lib/CodeGen/SjLjEHPrepare.cpp +++ b/lib/CodeGen/SjLjEHPrepare.cpp @@ -48,10 +48,10 @@ namespace { Constant *BuiltinSetjmpFn; Constant *FrameAddrFn; Constant *StackAddrFn; + Constant *StackRestoreFn; Constant *LSDAAddrFn; Value *PersonalityFn; Constant *CallSiteFn; - Constant *DispatchSetupFn; Constant *FuncCtxFn; Value *CallSite; public: @@ -107,11 +107,10 @@ bool SjLjEHPass::doInitialization(Module &M) { (Type *)0); FrameAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::frameaddress); StackAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::stacksave); + StackRestoreFn = Intrinsic::getDeclaration(&M, Intrinsic::stackrestore); BuiltinSetjmpFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_setjmp); LSDAAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_lsda); CallSiteFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_callsite); - DispatchSetupFn - = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_dispatch_setup); FuncCtxFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_functioncontext); PersonalityFn = 0; @@ -460,6 +459,25 @@ bool SjLjEHPass::setupEntryBlockAndCallSites(Function &F) { EntryBB->getTerminator()); Register->setDoesNotThrow(); + // Following any allocas not in the entry block, update the saved SP in the + // jmpbuf to the new value. + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { + if (BB == F.begin()) + continue; + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { + if (CallInst *CI = dyn_cast<CallInst>(I)) { + if (CI->getCalledFunction() != StackRestoreFn) + continue; + } else if (!isa<AllocaInst>(I)) { + continue; + } + Instruction *StackAddr = CallInst::Create(StackAddrFn, "sp"); + StackAddr->insertAfter(I); + Instruction *StoreStackAddr = new StoreInst(StackAddr, StackPtr, true); + StoreStackAddr->insertAfter(StackAddr); + } + } + // Finally, for any returns from this function, if this function contains an // invoke, add a call to unregister the function context. for (unsigned I = 0, E = Returns.size(); I != E; ++I) |