1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[EH] Keep filter clauses for types that have been caught.

The instruction combiner previously removed types from filter clauses in Landing Pad instructions if the type had previously been seen in a catch clause.  This is incorrect and prevents unexpected exception handlers from rethrowing the caught type.

Differential Revision: http://reviews.llvm.org/D14669

llvm-svn: 253370
This commit is contained in:
Andrew Kaylor 2015-11-17 20:13:04 +00:00
parent f27cb96b84
commit 459ce58049
2 changed files with 25 additions and 8 deletions

View File

@ -2486,10 +2486,24 @@ Instruction *InstCombiner::visitLandingPadInst(LandingPadInst &LI) {
SawCatchAll = true;
break;
}
if (AlreadyCaught.count(TypeInfo))
// Already caught by an earlier clause, so having it in the filter
// is pointless.
continue;
// Even if we've seen a type in a catch clause, we don't want to
// remove it from the filter. An unexpected type handler may be
// set up for a call site which throws an exception of the same
// type caught. In order for the exception thrown by the unexpected
// handler to propogate correctly, the filter must be correctly
// described for the call site.
//
// Example:
//
// void unexpected() { throw 1;}
// void foo() throw (int) {
// std::set_unexpected(unexpected);
// try {
// throw 2.0;
// } catch (int i) {}
// }
// There is no point in having multiple copies of the same typeinfo in
// a filter, so only add it if we didn't already.
if (SeenInFilter.insert(TypeInfo).second)

View File

@ -69,9 +69,11 @@ lpad.c:
filter [1 x i32*] [i32* @T1]
catch i32* @T2
unreachable
; Caught types should not be removed from filters
; CHECK: %c = landingpad
; CHECK-NEXT: @T1
; CHECK-NEXT: filter [0 x i32*]
; CHECK-NEXT: catch i32* @T1
; CHECK-NEXT: filter [1 x i32*] [i32* @T1]
; CHECK-NEXT: catch i32* @T2
; CHECK-NEXT: unreachable
lpad.d:
@ -87,9 +89,10 @@ lpad.e:
catch i32* @T1
filter [3 x i32*] [i32* @T1, i32* @T2, i32* @T2]
unreachable
; Caught types should not be removed from filters
; CHECK: %e = landingpad
; CHECK-NEXT: @T1
; CHECK-NEXT: filter [1 x i32*] [i32* @T2]
; CHECK-NEXT: catch i32* @T1
; CHECK-NEXT: filter [2 x i32*] [i32* @T1, i32* @T2]
; CHECK-NEXT: unreachable
lpad.f: