Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 5.5k
Propagate Type.GetInterfaces through dataflow analysis#114149
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
3bb48d626c5652eedb94c3165a37a32aeb0File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -524,7 +524,7 @@ Namespace Microsoft.VisualBasic.CompilerServices | ||
| Return System.Linq.Enumerable.ToArray(genericParameter.GetInterfaces) | ||
| End Function | ||
| Friend Shared Function GetClassConstraint(ByVal genericParameter As Type) As Type | ||
| Friend Shared Function GetClassConstraint(<DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)> ByVal genericParameter As Type) As <DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)> Type | ||
| 'Returns the class constraint for the type parameter, Nothing if it has | ||
| 'no class constraint. | ||
| Debug.Assert(IsGenericParameter(genericParameter), "expected type parameter") | ||
| @@ -931,9 +931,9 @@ Namespace Microsoft.VisualBasic.CompilerServices | ||
| ' For a WinRT object, we want to treat members of it's collection interfaces as members of the object | ||
| ' itself. So GetMembers calls here to find the member in all the collection interfaces that this object | ||
| ' implements. | ||
| <UnconditionalSuppressMessage("ReflectionAnalysis", "IL2065:UnrecognizedReflectionPattern", | ||
| <SuppressMessage("ReflectionAnalysis", "IL2065:UnrecognizedReflectionPattern", | ||
| Justification:="_type is annotated with .All, so it's Interfaces will be annotated as well and it is safe to call GetMember on the Interfaces. | ||
| We should be able to remove once https://github.com/mono/linker/issues/1731 is fixed.")> | ||
| We should be able to remove once https://github.com/dotnet/runtime/issues/114425 is fixed.")> | ||
| Friend Function LookupWinRTCollectionInterfaceMembers(ByVal memberName As String) As List(Of MemberInfo) | ||
| Debug.Assert(Me.IsWindowsRuntimeObject(), "Expected a Windows Runtime Object") | ||
| @@ -950,9 +950,6 @@ Namespace Microsoft.VisualBasic.CompilerServices | ||
| Return result | ||
| End Function | ||
| <UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern", | ||
MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This suppression was wrong, all that was needed was to annotate | ||
| Justification:="_type is annotated with .All, so it's BaseType will be annotated as well and it is safe to call GetMember on the BaseType. | ||
| We should be able to remove once https://github.com/mono/linker/issues/1731 is fixed.")> | ||
| Friend Function LookupNamedMembers(ByVal memberName As String) As MemberInfo() | ||
| 'Returns an array of members matching MemberName sorted by inheritance (most derived first). | ||
| 'If no members match MemberName, returns an empty array. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -45,7 +45,7 @@ internal ReflectedTypeData(Type type, bool isRegisteredType) | ||
| /// Retrieves custom attributes. | ||
| /// </summary> | ||
| [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2062:UnrecognizedReflectionPattern", | ||
| Justification = "_type is annotated as preserve All members, so any Types returned from GetInterfaces should be preserved as well once https://github.com/mono/linker/issues/1731 is fixed.")] | ||
MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The justification was incorrect, the warning is on lines working with elements of | ||
| Justification = "_type is annotated as preserve All members, so any Types returned from GetInterfaces should be preserved as well.")] | ||
| internal AttributeCollection GetAttributes() | ||
| { | ||
| // Worst case collision scenario: we don't want the perf hit | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| // Copyright (c) .NET Foundation and contributors. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Diagnostics; | ||
| using System.Diagnostics.CodeAnalysis; | ||
| using ILLink.Shared.DataFlow; | ||
| // This is needed due to NativeAOT which doesn't enable nullable globally yet | ||
| #nullable enable | ||
| namespace ILLink.Shared.TrimAnalysis | ||
| { | ||
| /// <summary> | ||
| /// Represents an array of <see cref="System.Type"/> where initially each element of the array has the same DynamicallyAccessedMembers annotation. | ||
| /// </summary> | ||
| internal sealed record ArrayOfAnnotatedSystemTypeValue : SingleValue | ||
| { | ||
| private readonly ValueWithDynamicallyAccessedMembers _initialValue; | ||
| public bool IsModified { get; private set; } | ||
| public ArrayOfAnnotatedSystemTypeValue (ValueWithDynamicallyAccessedMembers value) => _initialValue = value; | ||
| public override SingleValue DeepCopy () | ||
| { | ||
| return new ArrayOfAnnotatedSystemTypeValue (this); | ||
| } | ||
| public SingleValue GetAnyElementValue() | ||
| { | ||
| Debug.Assert (!IsModified); | ||
| return _initialValue; | ||
| } | ||
| public void MarkModified () => IsModified = true; | ||
| public override string ToString () => this.ValueToString (_initialValue.DynamicallyAccessedMemberTypes); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -250,6 +250,36 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers | ||
| } | ||
| break; | ||
| // | ||
| // GetInterfaces | ||
| // | ||
| case IntrinsicId.Type_GetInterfaces: { | ||
| if (instanceValue.IsEmpty ()) { | ||
| returnValue = MultiValueLattice.Top; | ||
| break; | ||
| } | ||
| var targetValue = _annotations.GetMethodThisParameterValue (calledMethod, DynamicallyAccessedMemberTypes.Interfaces); | ||
| foreach (var value in instanceValue.AsEnumerable ()) { | ||
| // Require Interfaces annotation | ||
| _requireDynamicallyAccessedMembersAction.Invoke (value, targetValue); | ||
| // Interfaces is transitive, so the return values will always have at least Interfaces annotation | ||
| DynamicallyAccessedMemberTypes returnMemberTypes = DynamicallyAccessedMemberTypes.Interfaces; | ||
| // Propagate All annotation across the call - All is a superset of Interfaces | ||
| if (value is ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers | ||
| && valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes == DynamicallyAccessedMemberTypes.All) | ||
| returnMemberTypes = DynamicallyAccessedMemberTypes.All; | ||
| // We model this as if each individual element of the returned array was returned from the GetInterfaces method call. | ||
| // It makes diagnostics fall out nicer because we now know where the Type comes from and where to assign blame, should the requirements not match | ||
| AddReturnValue (new ArrayOfAnnotatedSystemTypeValue(_annotations.GetMethodReturnValue (calledMethod, isNewObj: false, returnMemberTypes))); | ||
MichalStrehovsky marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| } | ||
| break; | ||
| // | ||
| // AssemblyQualifiedName | ||
| // | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.