[EH] Keep filter clauses for types that have been caught.
authorAndrew Kaylor <andrew.kaylor@intel.com>
Tue, 17 Nov 2015 20:13:04 +0000 (20:13 +0000)
committerAndrew Kaylor <andrew.kaylor@intel.com>
Tue, 17 Nov 2015 20:13:04 +0000 (20:13 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253370 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstructionCombining.cpp
test/Transforms/InstCombine/LandingPadClauses.ll

index 3ae7f08238b20f9137d44748cbe6953676b374fc..dbc963a2b35c946021564ecf578693acb52ae675 100644 (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)
index a4d77cbe8efb79cdfdaa7d9fc50bb15dbe9e9b21..75050c91bbb44ab5512e11b9c414fe488f0c1d1c 100644 (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: