From 881fcaec6be08d821de7df42fdbc99779717f59f Mon Sep 17 00:00:00 2001 From: Andrew Kaylor <andrew.kaylor@intel.com> Date: Tue, 17 Nov 2015 20:13:04 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253370 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstructionCombining.cpp | 22 +++++++++++++++---- .../InstCombine/LandingPadClauses.ll | 11 ++++++---- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index 3ae7f08238b..dbc963a2b35 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -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) diff --git a/test/Transforms/InstCombine/LandingPadClauses.ll b/test/Transforms/InstCombine/LandingPadClauses.ll index a4d77cbe8ef..75050c91bbb 100644 --- a/test/Transforms/InstCombine/LandingPadClauses.ll +++ b/test/Transforms/InstCombine/LandingPadClauses.ll @@ -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: -- 2.34.1