Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trimming: Reflection access to compiler generated methods produces warnings #85042

Closed
Tracked by #101149
vitek-karas opened this issue Apr 19, 2023 · 1 comment · Fixed by #104757
Closed
Tracked by #101149

Trimming: Reflection access to compiler generated methods produces warnings #85042

vitek-karas opened this issue Apr 19, 2023 · 1 comment · Fixed by #104757
Assignees
Labels
area-Tools-ILLink .NET linker development as well as trimming analyzers in-pr There is an active PR which will close this issue when it is merged
Milestone

Comments

@vitek-karas
Copy link
Member

Technically using reflection to access compiler generated methods could cause holes in trim analysis. This is because we don't analyze CG methods on their own, but only in the context of the user defined method which "owns" them. If they're invoked outside such context, the analysis may miss some incompatible behavior.

ILLink tried to mitigate this by producing warnings when we detect reflection access to CG method. Originally it produced warning always, but that was way too noisy. Modern C# produces lot of CG methods and using DAM annotations, it's really easy to accidentally "access" some of the CG methods "via reflection". So ILLink also implemented a heuristic, where it tried to detect if the method in question contains potentially dangerous code, this was done by looking for access to annotated members (mostly).

The end result of this is that ILLink can produce warnings IL2118, IL2119 and IL2120. These warnings are currently a "best effort" and there are cases where they don't need to be produced (overly aggressive heuristic in the ILLink). But there are also cases where they're not generated even though they should be (ILLink analysis doesn't catch everything in this case).

We considered implementing these in NativeAOT, but it proved to be problematic. The behavior of NativeAOT compiler is different enough, that the heuristic produces different results and there are cases were it produces warnings while ILLink doesn't. These places are also deep in internal structures of the NativeAOT runtime code, and suppressing these is problematic.

After a discussion we decided that we should not try to produce these warnings, and leave this as a known analysis hole. Reflection access to compiler generated methods is per C# "undefined behavior" and so it's already very problematic and should not be used. Combine this with trimming which will only make it slightly worse.

NativeAOT will not implement the necessary logic to produce IL2118, IL2119 and IL2120. We should probably remove these from ILLink eventually as well.

@vitek-karas vitek-karas added the area-Tools-ILLink .NET linker development as well as trimming analyzers label Apr 19, 2023
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Apr 19, 2023
@ghost
Copy link

ghost commented Apr 19, 2023

Tagging subscribers to this area: @agocke, @sbomer, @vitek-karas
See info in area-owners.md if you want to be subscribed.

Issue Details

Technically using reflection to access compiler generated methods could cause holes in trim analysis. This is because we don't analyze CG methods on their own, but only in the context of the user defined method which "owns" them. If they're invoked outside such context, the analysis may miss some incompatible behavior.

ILLink tried to mitigate this by producing warnings when we detect reflection access to CG method. Originally it produced warning always, but that was way too noisy. Modern C# produces lot of CG methods and using DAM annotations, it's really easy to accidentally "access" some of the CG methods "via reflection". So ILLink also implemented a heuristic, where it tried to detect if the method in question contains potentially dangerous code, this was done by looking for access to annotated members (mostly).

The end result of this is that ILLink can produce warnings IL2118, IL2119 and IL2120. These warnings are currently a "best effort" and there are cases where they don't need to be produced (overly aggressive heuristic in the ILLink). But there are also cases where they're not generated even though they should be (ILLink analysis doesn't catch everything in this case).

We considered implementing these in NativeAOT, but it proved to be problematic. The behavior of NativeAOT compiler is different enough, that the heuristic produces different results and there are cases were it produces warnings while ILLink doesn't. These places are also deep in internal structures of the NativeAOT runtime code, and suppressing these is problematic.

After a discussion we decided that we should not try to produce these warnings, and leave this as a known analysis hole. Reflection access to compiler generated methods is per C# "undefined behavior" and so it's already very problematic and should not be used. Combine this with trimming which will only make it slightly worse.

NativeAOT will not implement the necessary logic to produce IL2118, IL2119 and IL2120. We should probably remove these from ILLink eventually as well.

Author: vitek-karas
Assignees: -
Labels:

area-Tools-ILLink

Milestone: -

vitek-karas added a commit to vitek-karas/runtime that referenced this issue Apr 19, 2023
vitek-karas added a commit that referenced this issue Apr 24, 2023
…s warnings between ILLink and NativeAOT (#84770)

This enables the last of the disabled `RequiresCapability` tests for NativeAOT.

The implementation basically copies the logic from ILLink on how to produce warnings when method or field is marked due to reflection access.

We decided that producing warnings due to reflection access to compiler generated methods is more trouble than benefit and thus we won't do that anymore. See reasoning in #85042.

Otherwise the behavior in NativeAOT fully copies the one in ILLink (small exceptions due to better method overload resolution in NativeAOT).

High-level behavior changes in NativeAOT:
* Finally allow the NativeAOT compiler to produce IL2110, IL2111, IL2113 and IL2115
* Avoid generating warnings for override methods if the warning is already generated on the base method (for DAM marking)
* Implement correct marking (and warnings) for "DAM on type" when the derived class has broader annotation than the base class/interface (this is mostly to avoid noise warnings)
* Rename a set of methods and classes in data flow scanner to "Token", because they're only used when a given entity is accessed through its token (so `ldtoken` and similar). This allows for more precise handling of the cases above.

Testing changes:
* Allow specifying tool exceptions for `SkipKepItemsValidationAttribute` - this allows to enable one of the reflection tests for its diagnostics coverage, avoiding the necessity to fix everything around Kept behavior yet.
* Couple of fixes in the test validator to correctly compare expected/actual diagnostics

This fixes final bits of #68786
Fixes #68688
This helps with #82447
vitek-karas added a commit to vitek-karas/runtime that referenced this issue Apr 24, 2023
@agocke agocke added this to AppModel Jul 10, 2023
@agocke agocke added this to the 9.0.0 milestone Aug 9, 2023
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Aug 9, 2023
@sbomer sbomer self-assigned this Jun 7, 2024
@dotnet-policy-service dotnet-policy-service bot added the in-pr There is an active PR which will close this issue when it is merged label Jul 11, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Aug 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Tools-ILLink .NET linker development as well as trimming analyzers in-pr There is an active PR which will close this issue when it is merged
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants