diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSwitchManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSwitchManager.cs index 749b366a6af2be..7d406ce0be2963 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSwitchManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSwitchManager.cs @@ -289,8 +289,22 @@ public MethodIL GetMethodILWithInlinedSubstitutions(MethodIL method) if (delta >= 0 && delta < ehRegion.TryLength) { if (ehRegion.Kind == ILExceptionRegionKind.Filter) + { offsetsToVisit.Push(ehRegion.FilterOffset); + // Filter must end with endfilter, so ensure we don't accidentally remove it. + // ECMA-335 dictates that filter block starts at FilterOffset and ends at HandlerOffset. + int expectedEndfilterLocation = ehRegion.HandlerOffset - 2; + bool isValidFilter = expectedEndfilterLocation >= 0 + && (flags[expectedEndfilterLocation] & OpcodeFlags.InstructionStart) != 0 + && methodBytes[expectedEndfilterLocation] == (byte)ILOpcode.prefix1 + && methodBytes[expectedEndfilterLocation + 1] == unchecked((byte)ILOpcode.endfilter); + if (isValidFilter) + { + flags[expectedEndfilterLocation] |= OpcodeFlags.VisibleBasicBlockStart | OpcodeFlags.Mark; + } + } + offsetsToVisit.Push(ehRegion.HandlerOffset); // RyuJIT is going to look at this basic block even though it's unreachable.