Skip to content

Inference status: ICSharpCode.Decompiler #10

@dgrunwald

Description

@dgrunwald

The primary use-case (how I ended up starting this project) was trying to annotate ILSpy's decompiler engine, which quickly felt like a task that could be automated.

Timeline:

  • March 2010 (yes, over 10 years ago): I had an idea for a null checking analysis as an analysis on IL code. I implemented some of that idea, but it didn't work well enough for my liking and I gave up on the idea. The original idea of the nullability constraint graph (back then I called it "nullability subtyping graph") is from back then. So is the idea of using the minimum cut for minimizing the number of warnings (back then: errors reported by the analysis tool).
  • Early May 2020: I wanted to annotate ILSpy's decompiler engine (ICSharpCode.Decompiler) with nullable reference types. But it felt like a bunch of monotonous work that ought to be automated. I realized that the C# 8 nullable reference type system is somewhat similar to what I did 10 years earlier, and that my ideas may be applicable to an inference tool. An inference tool doesn't need to be perfect to be useful, it just needs automate the vast majority of the work.
  • 2020-05-09: I started building the NullabilityInference prototype.
  • 2020-05-17: The prototype can handle some individual code files from ICSharpCode.Decompiler.Utils
  • 2020-06-08: The prototype finally supports enough language features to run over the whole ICSharpCode.Decompiler without crashing with a NotImplementedException
    • Use .NET Core 3 + enable NRT, but not using inference --> 2714 warnings
    • After running InferNull --> 1134 warnings.
    • Some bugfixes reduce this to 1120 warnings.
  • 2020-06-13: Implementing flow analysis (Flow analysis #5) gets us down to 1079 warnings.
  • 2020-06-21: [NotNullWhen(true)]-inference finally works correctly --> 722 warnings.

In the remaining warnings, I see some categories of problems occurring repeatedly:

  • unconstrained generics: we can't infer [AllowNullable] yet
  • generics: we can't infer T: notnull constraints yet
  • uninitialized fields: ILSpy has many classes where fields are initialized not in the constructor, but by other methods (e.g. a single public method serves as an entry point for a class and initializes a bunch of fields; with private methods relying on the fields already being initialized)
  • Roslyn doesn't realize that fields are initialized when the ctor calls a property setter

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions