diff options
author | Sean Callanan <scallanan@apple.com> | 2012-07-21 02:02:15 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2012-07-21 02:02:15 +0000 |
commit | 6e6d4a6223384ecfd476dc5746ae25da8dd0b408 (patch) | |
tree | 16d1416c1ba15fdcc589243d47daf1c4cd54537e /lldb/source/Expression/IRForTarget.cpp | |
parent | 4c6d7a2ed2763fd02935bf539b647972ce58354a (diff) | |
download | bcm5719-llvm-6e6d4a6223384ecfd476dc5746ae25da8dd0b408.tar.gz bcm5719-llvm-6e6d4a6223384ecfd476dc5746ae25da8dd0b408.zip |
Added a fix that allows newly-constructed objects
to returned by expressions, by removing the
__cxa_atexit call that would normally cause these
objects to be destroyed. This also prevents many
errors of the form
Couldn't rewrite one of the arguments of a function call
error: Couldn't materialize struct: Structure hasn't been laid out yet
<rdar://problem/11309402>
llvm-svn: 160596
Diffstat (limited to 'lldb/source/Expression/IRForTarget.cpp')
-rw-r--r-- | lldb/source/Expression/IRForTarget.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Expression/IRForTarget.cpp index e5a93fc8fb7..5b98e2b6acb 100644 --- a/lldb/source/Expression/IRForTarget.cpp +++ b/lldb/source/Expression/IRForTarget.cpp @@ -1818,6 +1818,51 @@ IRForTarget::HandleObjCClass(Value *classlist_reference) } bool +IRForTarget::RemoveCXAAtExit (BasicBlock &basic_block) +{ + BasicBlock::iterator ii; + + std::vector<CallInst *> calls_to_remove; + + for (ii = basic_block.begin(); + ii != basic_block.end(); + ++ii) + { + Instruction &inst = *ii; + + CallInst *call = dyn_cast<CallInst>(&inst); + + // MaybeHandleCallArguments handles error reporting; we are silent here + if (!call) + continue; + + bool remove = false; + + llvm::Function *func = call->getCalledFunction(); + + if (func && func->getName() == "__cxa_atexit") + remove = true; + + llvm::Value *val = call->getCalledValue(); + + if (val && val->getName() == "__cxa_atexit") + remove = true; + + if (remove) + calls_to_remove.push_back(call); + } + + for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(), ce = calls_to_remove.end(); + ci != ce; + ++ci) + { + (*ci)->eraseFromParent(); + } + + return true; +} + +bool IRForTarget::ResolveCalls(BasicBlock &basic_block) { ///////////////////////////////////////////////////////////////////////// @@ -2684,6 +2729,16 @@ IRForTarget::runOnModule (Module &llvm_module) return false; } + + if (!RemoveCXAAtExit(*bbi)) + { + if (log) + log->Printf("RemoveCXAAtExit() failed"); + + // RemoveCXAAtExit() reports its own errors, so we don't do so here + + return false; + } } if (m_decl_map && m_execution_policy != lldb_private::eExecutionPolicyAlways) |