diff --git a/external/cecil b/external/cecil index 75fc419764f2..c600e6b9eb66 160000 --- a/external/cecil +++ b/external/cecil @@ -1 +1 @@ -Subproject commit 75fc419764f239dcdd679657316e6eae31e04dc2 +Subproject commit c600e6b9eb66dc45f13a6099079edc99091e795d diff --git a/src/linker/Linker.Steps/RemoveUnreachableBlocksStep.cs b/src/linker/Linker.Steps/RemoveUnreachableBlocksStep.cs index 0b91cc6623be..9ebb975418fc 100644 --- a/src/linker/Linker.Steps/RemoveUnreachableBlocksStep.cs +++ b/src/linker/Linker.Steps/RemoveUnreachableBlocksStep.cs @@ -591,6 +591,8 @@ BitArray GetReachableInstructionsMap (out List unreachableHand condBranches = new Stack (); condBranches.Push (GetInstructionIndex (handler.HandlerStart)); + if (handler.FilterStart != null) + condBranches.Push (GetInstructionIndex (handler.FilterStart)); } if (condBranches?.Count > 0) { diff --git a/test/Mono.Linker.Tests.Cases/UnreachableBlock/TryFilterBlocks.cs b/test/Mono.Linker.Tests.Cases/UnreachableBlock/TryFilterBlocks.cs new file mode 100644 index 000000000000..be36dbd0b089 --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/UnreachableBlock/TryFilterBlocks.cs @@ -0,0 +1,101 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.UnreachableBlock +{ + [SetupCSharpCompilerToUse ("csc")] + [SetupCompileArgument ("/optimize+")] + [SetupLinkerArgument ("--enable-opt", "ipconstprop")] + public class TryFilterBlocks + { + public static void Main () + { + TestUnreachableInsideTry (); + TestUnreachableInsideFilterCondition (); + } + + [Kept] + [ExpectedInstructionSequence (new[] { + "call", + "brfalse.s", + "call", + "leave.s", + "pop", + "call", + "ldc.i4.0", + "cgt.un", + "endfilter", + "pop", + "leave.s", + "ldc.i4.2", + "ret" + })] + [ExpectedExceptionHandlerSequence (new string[] { "filter" })] + static int TestUnreachableInsideTry () + { + try { + if (Prop) + Unreached_1 (); + + Reached_1 (); + } catch when (Log ()) { + } + + return 2; + } + + [Kept] + [ExpectedInstructionSequence (new[] { + "call", + "leave.s", + "pop", + "call", + "brfalse.s", + "ldc.i4.0", + "ldc.i4.0", + "cgt.un", + "endfilter", + "pop", + "leave.s", + "ldc.i4.3", + "ret" + })] + [ExpectedExceptionHandlerSequence (new string[] { "filter" })] + static int TestUnreachableInsideFilterCondition () + { + try { + Reached_2 (); + } catch when (Log () && Unreached_2 ()) { + } + + return 3; + } + + [Kept] + static bool Prop { + [Kept] + get { + return false; + } + } + + [Kept] + static bool Log () => false; + + [Kept] + static void Reached_1 () + { + } + + [Kept] + static void Reached_2 () + { + } + + static void Unreached_1 () + { + } + + static bool Unreached_2 () => true; + } +} \ No newline at end of file