Skip to content

Commit cd2b5fa

Browse files
fix exception filter
1 parent 331b387 commit cd2b5fa

File tree

3 files changed

+71
-0
lines changed

3 files changed

+71
-0
lines changed

src/coverlet.core/Symbols/CecilSymbolHelper.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ public static List<BranchPoint> GetBranchPoints(MethodDefinition methodDefinitio
4242
continue;
4343
}
4444

45+
if (BranchIsInGeneratedExceptionFilter(instruction, methodDefinition))
46+
continue;
47+
4548
if (BranchIsInGeneratedFinallyBlock(instruction, methodDefinition))
4649
continue;
4750

@@ -197,6 +200,35 @@ private static uint BuildPointsForSwitchCases(List<BranchPoint> list, BranchPoin
197200
return ordinal;
198201
}
199202

203+
private static bool BranchIsInGeneratedExceptionFilter(Instruction branchInstruction, MethodDefinition methodDefinition)
204+
{
205+
if (!methodDefinition.Body.HasExceptionHandlers)
206+
return false;
207+
208+
// a generated filter block will have no sequence points in its range
209+
var handlers = methodDefinition.Body.ExceptionHandlers
210+
.Where(e => e.HandlerType == ExceptionHandlerType.Filter)
211+
.ToList();
212+
213+
foreach (var exceptionHandler in handlers)
214+
{
215+
Instruction startFilter = exceptionHandler.FilterStart;
216+
Instruction endFilter = startFilter;
217+
218+
while(endFilter.OpCode != OpCodes.Endfilter && endFilter != null)
219+
{
220+
endFilter = endFilter.Next;
221+
}
222+
223+
if(branchInstruction.Offset >= startFilter.Offset && branchInstruction.Offset <= endFilter.Offset)
224+
{
225+
return true;
226+
}
227+
}
228+
229+
return false;
230+
}
231+
200232
private static bool BranchIsInGeneratedFinallyBlock(Instruction branchInstruction, MethodDefinition methodDefinition)
201233
{
202234
if (!methodDefinition.Body.HasExceptionHandlers)

test/coverlet.core.tests/Samples/Samples.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,4 +210,31 @@ public string Method(string input)
210210
return input;
211211
}
212212
}
213+
214+
public class ExceptionFilter
215+
{
216+
public void Test()
217+
{
218+
try
219+
{
220+
int a = 0;
221+
int b = 1;
222+
int c = b / a;
223+
}
224+
catch (Exception ex) when (True() && False())
225+
{
226+
Console.WriteLine(ex.Message);
227+
}
228+
}
229+
230+
public bool True()
231+
{
232+
return true;
233+
}
234+
235+
public bool False()
236+
{
237+
return false;
238+
}
239+
}
213240
}

test/coverlet.core.tests/Symbols/CecilSymbolHelperTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,5 +259,17 @@ public void GetBranchPoints_IgnoresSwitchIn_GeneratedMoveNext()
259259
Assert.Empty(points);
260260

261261
}
262+
263+
[Fact]
264+
public void GetBranchPoints_ExceptionFilter()
265+
{
266+
// arrange
267+
var type = _module.Types.First(x => x.FullName == typeof(ExceptionFilter).FullName);
268+
var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(ExceptionFilter.Test)}"));
269+
// act
270+
var points = CecilSymbolHelper.GetBranchPoints(method);
271+
272+
Assert.Empty(points);
273+
}
262274
}
263275
}

0 commit comments

Comments
 (0)