summaryrefslogtreecommitdiffstats
path: root/lldb/source/Expression/IRForTarget.cpp
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2012-07-21 02:02:15 +0000
committerSean Callanan <scallanan@apple.com>2012-07-21 02:02:15 +0000
commit6e6d4a6223384ecfd476dc5746ae25da8dd0b408 (patch)
tree16d1416c1ba15fdcc589243d47daf1c4cd54537e /lldb/source/Expression/IRForTarget.cpp
parent4c6d7a2ed2763fd02935bf539b647972ce58354a (diff)
downloadbcm5719-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.cpp55
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)
OpenPOWER on IntegriCloud