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

Annotate more of CoreLib for trimming #38265

Merged
merged 5 commits into from
Jun 24, 2020

Conversation

MichalStrehovsky
Copy link
Member

@MichalStrehovsky MichalStrehovsky commented Jun 23, 2020

Yet another batch of trimming annotations.

Resolves #32921.

Yet another batch of trimming annotations.
@@ -72,6 +72,7 @@ public override IList<CustomAttributeData> GetCustomAttributesData()

// GetDefaultMembers
// This will return a MemberInfo that has been marked with the [DefaultMemberAttribute]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Why All? The doc says it can be only constructor, method, property, or field and I think they have to be public

Copy link
Member Author

Choose a reason for hiding this comment

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

The doc says it can be only constructor, method, property, or field and I think they have to be public

Couldn't find that mention in the doc - the impl also works for events and nested types. It's a janky API.

It was forced by the annotation on GetMember. I've fixed that up.

@@ -72,6 +72,7 @@ public override IList<CustomAttributeData> GetCustomAttributesData()

// GetDefaultMembers
// This will return a MemberInfo that has been marked with the [DefaultMemberAttribute]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Does the attribute have any effect here when the type is sealed?

Copy link
Member

Choose a reason for hiding this comment

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

The attribute is on the "this" - which is a special case - it annotates the type this RuntimeType represents. So for example calling typeof<MyType>.GetDefaultMembers() would end up (due to this attribute) marking the entire MyType.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure but as this is C# code there won't be any call (IL reference) to this method

Copy link
Member

Choose a reason for hiding this comment

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

Note that the same annotation is on Type.GetDefaultMembers() - the current data flow implementation in the linker assumes that the entire inheritance hierarchy for a given method has the same annotations (We're missing the validation in the linker for now dotnet/linker#1028).

Other than the above rule, this also means that when analyzing the method body of this method the linker can make assumptions about the this and won't generate warnings...

@@ -339,6 +339,7 @@ public virtual Type[] GetGenericParameterConstraints()
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
public abstract PropertyInfo[] GetProperties(BindingFlags bindingAttr);

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Why All (that includes NestedTypes as well) ? The doc says it can be only constructor, method, property, or field and I think they have to be public

Copy link
Member

@vitek-karas vitek-karas left a comment

Choose a reason for hiding this comment

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

Other than the comment about All it looks good.

@@ -92,6 +93,8 @@ internal static bool TrackAsyncMethodCompletion
/// <summary>Gets a description of the state of the state machine object, suitable for debug purposes.</summary>
/// <param name="stateMachine">The state machine object.</param>
/// <returns>A description of the state machine.</returns>
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern",
Copy link
Member

Choose a reason for hiding this comment

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

Can we close #32921 with this?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yup

@@ -100,6 +100,8 @@ public static partial class Activator

[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern",
Justification = "Implementation detail of Activator that linker intrinsically recognizes")]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:UnrecognizedReflectionPattern",
Copy link
Member

Choose a reason for hiding this comment

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

Why are IL2006 and IL2026 both UnrecognizedReflectionPattern ? Shouldn't different warning numbers have different titles/names?

Copy link
Member

Choose a reason for hiding this comment

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

@mateoatr to comment on the second parameter values...

Copy link
Contributor

Choose a reason for hiding this comment

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

Anything that is put after the colon in the CheckId parameter is used only for documentation purposes (this is, the warning suppression mechanism completely ignores what the user puts after the colon, it only cares for the four numbers of the warning id).
We sometimes put a subcategory on the warnings to further categorize them, although this specific warning does not have the UnrecognizedReflectionPattern subcategory, I don't know if we should add it.

Copy link
Member

Choose a reason for hiding this comment

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

It is super confusing as a reader to see 2 warning numbers with the same string. What is the title of IL2026? RequiresUnreferencedCode? We should update it here so this doesn't look like duplicated attributes.

Copy link
Member Author

Choose a reason for hiding this comment

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

Renamed to RequiresUnreferencedCode.

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

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

Just a couple clarifying questions. LGTM

| DynamicallyAccessedMemberTypes.PublicFields
| DynamicallyAccessedMemberTypes.PublicNestedTypes)]
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern",
Justification = "Linker doesn't recongnize GetMember(BindingFlags.Public) but this is what the body is doing")]
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: typo in recongnize

| DynamicallyAccessedMemberTypes.PublicEvents
| DynamicallyAccessedMemberTypes.PublicProperties
| DynamicallyAccessedMemberTypes.PublicConstructors
| DynamicallyAccessedMemberTypes.PublicFields
Copy link
Member

Choose a reason for hiding this comment

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

PublicFields is there twice

| DynamicallyAccessedMemberTypes.PublicEvents
| DynamicallyAccessedMemberTypes.PublicProperties
| DynamicallyAccessedMemberTypes.PublicConstructors
| DynamicallyAccessedMemberTypes.PublicFields
Copy link
Member

Choose a reason for hiding this comment

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

Same as above - duplicate PublicFields

Copy link
Member

Choose a reason for hiding this comment

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

And also below some more...

Copy link
Member Author

Choose a reason for hiding this comment

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

Sigh. Fixed.

I hope the one user of this useless API is going to appreciate the size savings from the restriction on .All because we just spent quite a bit of Microsoft money on this.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this is an indicator we are missing DynamicallyAccessedMemberTypes.AllPublic enum value

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe this is an indicator we are missing DynamicallyAccessedMemberTypes.AllPublic enum value

We can consider that - would that annotation be useful outside these two rarely used APIs?

@MichalStrehovsky MichalStrehovsky merged commit 188a3a8 into dotnet:master Jun 24, 2020
@MichalStrehovsky MichalStrehovsky deleted the annotmore branch June 24, 2020 11:13
@ghost ghost locked as resolved and limited conversation to collaborators Dec 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

GetAsyncStateMachineDescription may change behavior on app processed by ILLink
6 participants