From: Bob Wilson Date: Wed, 16 Nov 2011 07:12:00 +0000 (+0000) Subject: Update the SP in the SjLj jmpbuf whenever it changes. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=20c918dfed5830f6d0c54c9c38817bd660cb6a13;p=oota-llvm.git Update the SP in the SjLj jmpbuf whenever it changes. 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 --- diff --git a/lib/CodeGen/SjLjEHPrepare.cpp b/lib/CodeGen/SjLjEHPrepare.cpp index ac88441bf9a..5d60bc9b751 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(I)) { + if (CI->getCalledFunction() != StackRestoreFn) + continue; + } else if (!isa(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)