From dbb51b0d90603b54bbdca657902c56eafd7a32cb Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Thu, 21 Jul 2022 14:56:11 -0700 Subject: 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. --- src/ILLink.RoslynAnalyzer/TrimAnalysis/FlowAnnotations.cs | 5 ----- src/linker/Linker.Dataflow/FlowAnnotations.cs | 6 +++++- src/linker/Linker.Steps/MarkStep.cs | 2 +- src/linker/Linker/Annotations.cs | 2 +- .../DataFlow/CompilerGeneratedCodeAccessedViaReflection.cs | 10 ---------- 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; /// 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 (method)) + if (FlowAnnotations.RequiresVirtualMethodDataFlowAnalysis (method) || HasLinkerAttribute (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), "", - ProducedBy = ProducedBy.Trimmer)] () => { RequiresAllOnT (); }; @@ -548,8 +546,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow { public static void Test () { - [ExpectedWarning ("IL2118", nameof (LocalFunctionWhichMarksItself), "", - ProducedBy = ProducedBy.Trimmer)] void LocalFunction () { RequiresAllOnT (); @@ -561,7 +557,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow class IteratorWhichMarksItself { - [ExpectedWarning ("IL2118", ProducedBy = ProducedBy.Trimmer, CompilerGeneratedCode = true)] public static IEnumerable 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 (); @@ -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 (); -- cgit v1.2.3