diff options
author | Sven Boemer <sbomer@gmail.com> | 2022-07-22 00:56:11 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-22 00:56:11 +0300 |
commit | dbb51b0d90603b54bbdca657902c56eafd7a32cb (patch) | |
tree | 3b0b0d22675f98f1c21e7e49a373b34d5c524a12 | |
parent | 58091524639f81a4733dcd66510d79341d3aa1b1 (diff) |
Avoid dataflow analysis for generic parameters (#2908)
This avoids unnecessarily running the reflection methodbody scanner in
the linker, and the dataflow analysis in the analyzer, for methods
that were previously only triggering dataflow analysis due to
annotated generic parameters.
This eliminates unnecessary warnings for reflection access to
compiler-generated code.
5 files changed, 7 insertions, 18 deletions
diff --git a/src/ILLink.RoslynAnalyzer/TrimAnalysis/FlowAnnotations.cs b/src/ILLink.RoslynAnalyzer/TrimAnalysis/FlowAnnotations.cs index 28e56e563..533ef6a83 100644 --- a/src/ILLink.RoslynAnalyzer/TrimAnalysis/FlowAnnotations.cs +++ b/src/ILLink.RoslynAnalyzer/TrimAnalysis/FlowAnnotations.cs @@ -34,11 +34,6 @@ namespace ILLink.Shared.TrimAnalysis return true; } - foreach (var typeParameter in method.TypeParameters) { - if (typeParameter.GetDynamicallyAccessedMemberTypes () != DynamicallyAccessedMemberTypes.None) - return true; - } - return false; } diff --git a/src/linker/Linker.Dataflow/FlowAnnotations.cs b/src/linker/Linker.Dataflow/FlowAnnotations.cs index 610cd1f59..472f8567f 100644 --- a/src/linker/Linker.Dataflow/FlowAnnotations.cs +++ b/src/linker/Linker.Dataflow/FlowAnnotations.cs @@ -28,12 +28,16 @@ namespace ILLink.Shared.TrimAnalysis } public bool RequiresDataFlowAnalysis (MethodDefinition method) => + GetAnnotations (method.DeclaringType).TryGetAnnotation (method, out var methodAnnotations) + && (methodAnnotations.ReturnParameterAnnotation != DynamicallyAccessedMemberTypes.None || methodAnnotations.ParameterAnnotations != null); + + public bool RequiresVirtualMethodDataFlowAnalysis (MethodDefinition method) => GetAnnotations (method.DeclaringType).TryGetAnnotation (method, out _); public bool RequiresDataFlowAnalysis (FieldDefinition field) => GetAnnotations (field.DeclaringType).TryGetAnnotation (field, out _); - public bool RequiresDataFlowAnalysis (GenericParameter genericParameter) => + public bool RequiresGenericArgumentDataFlowAnalysis (GenericParameter genericParameter) => GetGenericParameterAnnotation (genericParameter) != DynamicallyAccessedMemberTypes.None; /// <summary> diff --git a/src/linker/Linker.Steps/MarkStep.cs b/src/linker/Linker.Steps/MarkStep.cs index 6d19bcc76..bd174519e 100644 --- a/src/linker/Linker.Steps/MarkStep.cs +++ b/src/linker/Linker.Steps/MarkStep.cs @@ -2622,7 +2622,7 @@ namespace Mono.Linker.Steps TypeDefinition? argumentTypeDef = MarkType (argument, new DependencyInfo (DependencyKind.GenericArgumentType, instance)); - if (Annotations.FlowAnnotations.RequiresDataFlowAnalysis (parameter)) { + if (Annotations.FlowAnnotations.RequiresGenericArgumentDataFlowAnalysis (parameter)) { // The only two implementations of IGenericInstance both derive from MemberReference Debug.Assert (instance is MemberReference); diff --git a/src/linker/Linker/Annotations.cs b/src/linker/Linker/Annotations.cs index c2304e379..c5ceeabe9 100644 --- a/src/linker/Linker/Annotations.cs +++ b/src/linker/Linker/Annotations.cs @@ -678,7 +678,7 @@ namespace Mono.Linker if (!method.IsVirtual) return; - if (FlowAnnotations.RequiresDataFlowAnalysis (method) || HasLinkerAttribute<RequiresUnreferencedCodeAttribute> (method)) + if (FlowAnnotations.RequiresVirtualMethodDataFlowAnalysis (method) || HasLinkerAttribute<RequiresUnreferencedCodeAttribute> (method)) VirtualMethodsWithAnnotationsToValidate.Add (method); } } diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeAccessedViaReflection.cs b/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeAccessedViaReflection.cs index a05e25439..347358f90 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeAccessedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeAccessedViaReflection.cs @@ -534,8 +534,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow public static void Test () { var a = - [ExpectedWarning ("IL2118", nameof (LambdaWhichMarksItself), "<Test>", - ProducedBy = ProducedBy.Trimmer)] () => { RequiresAllOnT<LambdaWhichMarksItself> (); }; @@ -548,8 +546,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow { public static void Test () { - [ExpectedWarning ("IL2118", nameof (LocalFunctionWhichMarksItself), "<Test>", - ProducedBy = ProducedBy.Trimmer)] void LocalFunction () { RequiresAllOnT<LocalFunctionWhichMarksItself> (); @@ -561,7 +557,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow class IteratorWhichMarksItself { - [ExpectedWarning ("IL2118", ProducedBy = ProducedBy.Trimmer, CompilerGeneratedCode = true)] public static IEnumerable<int> Test () { yield return 0; @@ -574,7 +569,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow class AsyncWhichMarksItself { - [ExpectedWarning ("IL2118", ProducedBy = ProducedBy.Trimmer, CompilerGeneratedCode = true)] public static async void Test () { await MethodAsync (); @@ -599,8 +593,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow class LocalFunctionWhichMarksItselfOnlyAccessedViaReflection { - [ExpectedWarning ("IL2118", nameof (LocalFunctionWhichMarksItselfOnlyAccessedViaReflection), "<" + nameof (ClassWithLocalFunction.MethodWithLocalFunction) + ">", "LocalFunction", - ProducedBy = ProducedBy.Trimmer)] public static void Test () { RequiresNonPublicMethodsOnT<ClassWithLocalFunction> (); @@ -610,8 +602,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow { public static void MethodWithLocalFunction () { - [ExpectedWarning ("IL2118", nameof (LocalFunctionWhichMarksItselfOnlyAccessedViaReflection), "<" + nameof (MethodWithLocalFunction) + ">", nameof (LocalFunction), - ProducedBy = ProducedBy.Trimmer)] static void LocalFunction () { RequiresNonPublicMethodsOnT<ClassWithLocalFunction> (); |