summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2011-11-16 07:12:00 +0000
committerBob Wilson <bob.wilson@apple.com>2011-11-16 07:12:00 +0000
commit20c918dfed5830f6d0c54c9c38817bd660cb6a13 (patch)
tree824466449ac7fd1262f53f97dbc3d49f777ed6e6
parenteaab6ef6eb12fc950f1d4371b297d9b7ca9d4c66 (diff)
downloadexternal_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.cpp24
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)