Compiler-generated code analysis relies on definite assignment
- Dominant language
- C#
- Stars
- 392
- Forks
- 128
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 2
Description
https://github.com/dotnet/linker/pull/2842 tracks assignments to hoisted locals within a group of compiler-generated methods. It uses `Top` as the default value for hoisted locals, instead of `UnknownValue.Instance`, to avoid excess warnings.
Consider this [example](https://sharplab.io/#v2:EYLgtghglgdgNAExAagD4AEBMBGAsAKHQAYACdbAOgBEoIBzGAewGcAXKAY2YoGFGEApgEEYEADYBPZlGYBuAsTLYALPMIBmMphI8SAbwIkjZTeQBsS9QB5YrAHwkAsgAoAKhIAOAkgFcYAayYAdxh3LwBKfUNjGPJsMgB2EiI1GJiAJQEARx8oACdhMTFnP0DGELCBcNTjAF9oowalC3RlEkyc/MLigG0qCVEwTnFJIQ4OAWZmAQRHATBgATzmZ37B4aKJMYmpmbmFpcruISLwgF0SSpJWSL16/FqgA):
```csharp
using System;
using System.Diagnostics.CodeAnalysis;
using System.Collections.Generic;
public class C {
public static IEnumerable M(Type unknownType) {
yield return 0;
RequireAll(unknownType);
}
static void RequireAll([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type t) {}
}
```
The compiler generates two fields on the state machine type, `unknownType` and `<>3__unknownType`:
- `M` assigns `<>3__unknownType` from the method parameter
- `GetEnumerator` assigns `unknownType` from `<>3__unknownType`
- `MoveNext` reads `unknownType`
If the default value were `UnknownValue.Instance`, we would get an extra warning (unknown value passed to `RequireAll`). To prevent this we currently rely on definite assignment, which should guarantee that some assigned value reaches the point of consumption, so `Top` shouldn't be an analysis hole.
But as @vitek-karas pointed out in https://github.com/dotnet/linker/pull/2842#discussion_r909382653, we would ideally not rely on this for general IL analysis. We could potentially improve this by making the default value `UnknownValue.Instance`, but analyzing state machine methods in a specific order so that assignments override the default unknown value. It would mean making the analysis flow-sensitive instead of tracking all assigned values (similar for nested functions).
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.