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

Implement data flow annotations on generic parameters #1245

Merged
merged 7 commits into from
Jun 16, 2020

Conversation

vitek-karas
Copy link
Member

The checks are done when linker calls MarkType(TypeReference) or MarkMethod(MethodReference). The check itself is straightforward as it uses existing functionality.

Added annotations in FlowAnnotations for generic parameters.

Added one parameter to MarkType to better track the location where the type reference comes from. This enables much more precise reporting of warnings.

On test side this makes the recognized/unrecognized attributes applicable to many more things as warnings can come from types, fields and so on.

Fixes #1086

@vitek-karas
Copy link
Member Author

This is still missing making MakeGenericType and MakeGenericMethod potentially linker unfriendly, but I wanted to get early feedback on the core of the changes.

@MichalStrehovsky
Copy link
Member

Looks reasonable. Would it make sense to treat new() constraint as an implicit PublicParameterlessConstructor annotation on the parameter?

src/linker/Linker.Dataflow/FlowAnnotations.cs Show resolved Hide resolved
src/linker/Linker.Dataflow/MethodBodyScanner.cs Outdated Show resolved Hide resolved
{
while (type is TypeSpecification specification) {
if (type is GenericInstanceType git) {
MarkGenericArguments (git);
MarkGenericArguments (git, sourceLocationMember ?? (reason.Source as IMemberDefinition) ?? (reason.Source as MemberReference)?.Resolve ());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer if reason.Source was not used in this context as I have no confidence in the value and we have no tests for that

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case we would have to pass the new parameter on every call to MarkType and I would have to add a similar parameter to MarkMethod and also pass it everywhere.

I actually did that at first, but it turned out that in almost all cases we passed the same value to that new parameter as we do to reason.Source.

So in a way the tests for this new functionality would also validate the reason.Source.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I propagated the source member explicitly - this spreads everywhere, so the change is large (almost all of mark step), but mostly it's just mechanical.

@vitek-karas vitek-karas marked this pull request as ready for review June 8, 2020 08:39
@vitek-karas
Copy link
Member Author

@MichalStrehovsky @marek-safar can you please take a look again - it should be complete now.

Copy link
Member

@MichalStrehovsky MichalStrehovsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me otherwise

src/linker/Linker.Dataflow/ValueNode.cs Show resolved Hide resolved
methodAnnotations.TryGetAnnotation (genericParameter, out var annotation))
return annotation.Annotation;

return DynamicallyAccessedMemberTypes.None;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: redundant return?

The checks are done when linker calls MarkType(TypeReference) or MarkMethod(MethodReference). The check itself is straightforward as it uses existing functionality.

Added annotations in FlowAnnotations for generic parameters.

Added one parameter to MarkType to better track the location where the type reference comes from. This enables much more precise reporting of warnings.

On test side this makes the recognized/unrecognized attributes applicable to many more things as warnings can come from types, fields and so on.
Data flow on generic parameters makes any generic instantiation potentially problematic. So we need to start marking MakeGenericType and MakeGenericMethod as problematic as well.

MakeGenericType is possible to only warn when there are generic parameters with annotations. For MakeGenericMethod we can't do anything special as we don't track MethodInfo instances.
@vitek-karas vitek-karas merged commit c75e881 into dotnet:master Jun 16, 2020
@vitek-karas vitek-karas deleted the GenericParameterDataFlow branch June 16, 2020 09:48
tkapin pushed a commit to tkapin/runtime that referenced this pull request Jan 31, 2023
…1245)

* Implement data flow annotations on generic parameters

The checks are done when linker calls MarkType(TypeReference) or MarkMethod(MethodReference). The check itself is straightforward as it uses existing functionality.

Added annotations in FlowAnnotations for generic parameters.

Added one parameter to MarkType to better track the location where the type reference comes from. This enables much more precise reporting of warnings.

On test side this makes the recognized/unrecognized attributes applicable to many more things as warnings can come from types, fields and so on.

* Recognize MakeGenericType/Method and warn on them

Data flow on generic parameters makes any generic instantiation potentially problematic. So we need to start marking MakeGenericType and MakeGenericMethod as problematic as well.

MakeGenericType is possible to only warn when there are generic parameters with annotations. For MakeGenericMethod we can't do anything special as we don't track MethodInfo instances.

Commit migrated from dotnet/linker@c75e881
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[feature/dataflow] Allow DynamicallyAccessedMembers on generic types
3 participants