aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2007-08-27 15:47:50 +0000
committerDuncan Sands <baldrick@free.fr>2007-08-27 15:47:50 +0000
commit923fdb10d27aede037ce7aacda78f69f5e29bb00 (patch)
treeabbc2f1ee9dd21367b0e5befed02ec2616ae4d9a /lib
parent9ba5d4d7fcdb4f9326645c18535a82d80fea8e49 (diff)
downloadexternal_llvm-923fdb10d27aede037ce7aacda78f69f5e29bb00.tar.gz
external_llvm-923fdb10d27aede037ce7aacda78f69f5e29bb00.tar.bz2
external_llvm-923fdb10d27aede037ce7aacda78f69f5e29bb00.zip
There is an impedance matching problem between LLVM and
gcc exception handling: if an exception unwinds through an invoke, then execution must branch to the invoke's unwind target. We previously tried to enforce this by appending a cleanup action to every selector, however this does not always work correctly due to an optimization in the C++ unwinding runtime: if only cleanups would be run while unwinding an exception, then the program just terminates without actually executing the cleanups, as invoke semantics would require. I was hoping this wouldn't be a problem, but in fact it turns out to be the cause of all the remaining failures in the LLVM testsuite (these also fail with -enable-correct-eh-support, so turning on -enable-eh didn't make things worse!). Instead we need to append a full-blown catch-all to the end of each selector. The correct way of doing this depends on the personality function, i.e. it is language dependent, so can only be done by gcc. Thus this patch which generalizes the eh.selector intrinsic so that it can handle all possible kinds of action table entries (before it didn't accomodate cleanups): now 0 indicates a cleanup, and filters have to be specified using the number of type infos plus one rather than the number of type infos. Related gcc patches will cause Ada to pass a cleanup (0) to force the selector to always fire, while C++ will use a C++ catch-all (null). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41484 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/MachineModuleInfo.cpp7
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp18
2 files changed, 19 insertions, 6 deletions
diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp
index 77fb643b65..62224fdca8 100644
--- a/lib/CodeGen/MachineModuleInfo.cpp
+++ b/lib/CodeGen/MachineModuleInfo.cpp
@@ -1726,6 +1726,13 @@ void MachineModuleInfo::addFilterTypeInfo(MachineBasicBlock *LandingPad,
LP.TypeIds.push_back(getFilterIDFor(IdsInFilter));
}
+/// addCleanup - Add a cleanup action for a landing pad.
+///
+void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) {
+ LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
+ LP.TypeIds.push_back(0);
+}
+
/// TidyLandingPads - Remap landing pad labels and remove any deleted landing
/// pads.
void MachineModuleInfo::TidyLandingPads() {
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 7439e617d3..12024ff603 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -2519,7 +2519,7 @@ static void addCatchInfo(CallInst &I, MachineModuleInfo *MMI,
for (unsigned i = N - 1; i > 2; --i) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(i))) {
unsigned FilterLength = CI->getZExtValue();
- unsigned FirstCatch = i + FilterLength + 1;
+ unsigned FirstCatch = i + FilterLength + !FilterLength;
assert (FirstCatch <= N && "Invalid filter length");
if (FirstCatch < N) {
@@ -2530,11 +2530,17 @@ static void addCatchInfo(CallInst &I, MachineModuleInfo *MMI,
TyInfo.clear();
}
- TyInfo.reserve(FilterLength);
- for (unsigned j = i + 1; j < FirstCatch; ++j)
- TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
- MMI->addFilterTypeInfo(MBB, TyInfo);
- TyInfo.clear();
+ if (!FilterLength) {
+ // Cleanup.
+ MMI->addCleanup(MBB);
+ } else {
+ // Filter.
+ TyInfo.reserve(FilterLength - 1);
+ for (unsigned j = i + 1; j < FirstCatch; ++j)
+ TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
+ MMI->addFilterTypeInfo(MBB, TyInfo);
+ TyInfo.clear();
+ }
N = i;
}