Skip to content

Commit

Permalink
Identify null primitive constants in the debug scopes
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveGilham committed Sep 10, 2022
1 parent c4bfd8b commit 5834548
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
30 changes: 30 additions & 0 deletions AltCover.Engine/CecilEx.fs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ open System.Reflection

open Mono.Cecil
open Mono.Cecil.Cil
open Mono.Cecil.Metadata

module AssemblyConstants =
let internal nugetCache =
Expand Down Expand Up @@ -190,12 +191,38 @@ module internal CecilExtension =
System.Reflection.BindingFlags.Instance
||| System.Reflection.BindingFlags.NonPublic)

let etypeField =
typeof<TypeReference>.GetField
("etype",
System.Reflection.BindingFlags.Instance
||| System.Reflection.BindingFlags.NonPublic)

let internal offsetTable =
System.Collections.Generic.SortedDictionary<int, Instruction>()

let unresolved (point: InstructionOffset) =
isResolvedProp.GetValue(point) :?> bool |> not

let checkScopeConstants (m: MethodDefinition) =
scopesSeen
|> Seq.iter(fun scope -> let sus = scope.Constants
|> Seq.filter (fun c -> (isNull c.Value) &&
match etypeField.GetValue(c.ConstantType) :?> byte with
| 0x14uy // ElementType.Array
| 0x1duy // ElementType.SzArray
| 0x12uy // ElementType.Class
| 0x1cuy // ElementType.Object
| 0x00uy // ElementType.None
| 0x13uy // ElementType.Var
| 0x1euy // ElementType.MVar
| 0x0euy // ElementType.String
-> false
| _ -> true)
|> Seq.toList
sus |> Seq.iter (fun c -> scope.Constants.Remove c |> ignore
sprintf "Null Primitive Constant %s in method %s" c.Name m.FullName
|> Output.warn))

let prepareLocalScopes (m: MethodDefinition) =
offsetTable.Clear()
scopesSeen.Clear()
Expand Down Expand Up @@ -238,6 +265,9 @@ module internal CecilExtension =
scope.End <- resolvePoint scope.End

m.DebugInformation.Scope |> resolveScope

checkScopeConstants m

pruneLocalScopes m

// Adjust the IL for exception handling
Expand Down
21 changes: 21 additions & 0 deletions AltCover.Tests/Tests2.fs
Original file line number Diff line number Diff line change
Expand Up @@ -923,8 +923,14 @@ has been prefixed with Ldc_I4_1 (1 byte)

let size = finish.Offset + finish.GetSize()

let f = pathGetterDef.Body.Instructions.[2].Operand :?> FieldDefinition
let primitive = f.FieldType
let np = ArrayType(primitive, 23)

pathGetterDef.DebugInformation.Scope <- rescope

let bexpect = System.Text.StringBuilder()

[ -1
4
finish.Offset
Expand All @@ -935,10 +941,22 @@ has been prefixed with Ldc_I4_1 (1 byte)
let s = ScopeDebugInformation(start, null)
s.Start <- InstructionOffset(i)
s.End <- InstructionOffset(size)
let n = i.ToString().Replace("-", "_")
s.Constants.Add <| ConstantDebugInformation("I"+n, primitive, null)
s.Constants.Add <| ConstantDebugInformation("A"+n, np, null)

sprintf "Null Primitive Constant I%s in method System.Boolean Sample31.Class3/Class4::get_Defer()" n
|> bexpect.AppendLine
|> ignore
rescope.Scopes.Add s)

rescope.Scopes.Add rescope

let save = Output.warn
let b = System.Text.StringBuilder()

Output.warn <- b.AppendLine >> ignore

prepareLocalScopes pathGetterDef

Assert.True(
Expand Down Expand Up @@ -966,6 +984,9 @@ has been prefixed with Ldc_I4_1 (1 byte)
|> Seq.toList

test <@ result = expected @>
test <@ b.ToString() = bexpect.ToString() @>

Output.warn <- save

[<Test>]
let ShouldWriteMonoAssemblyOK () =
Expand Down

0 comments on commit 5834548

Please sign in to comment.