Skip to content

Commit dbb51b0

Browse files
authored
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.
1 parent 5809152 commit dbb51b0

File tree

5 files changed

+7
-18
lines changed

5 files changed

+7
-18
lines changed

src/ILLink.RoslynAnalyzer/TrimAnalysis/FlowAnnotations.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,6 @@ public static bool RequiresDataFlowAnalysis (IMethodSymbol method)
3434
return true;
3535
}
3636

37-
foreach (var typeParameter in method.TypeParameters) {
38-
if (typeParameter.GetDynamicallyAccessedMemberTypes () != DynamicallyAccessedMemberTypes.None)
39-
return true;
40-
}
41-
4237
return false;
4338
}
4439

src/linker/Linker.Dataflow/FlowAnnotations.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,16 @@ public FlowAnnotations (LinkContext context)
2828
}
2929

3030
public bool RequiresDataFlowAnalysis (MethodDefinition method) =>
31+
GetAnnotations (method.DeclaringType).TryGetAnnotation (method, out var methodAnnotations)
32+
&& (methodAnnotations.ReturnParameterAnnotation != DynamicallyAccessedMemberTypes.None || methodAnnotations.ParameterAnnotations != null);
33+
34+
public bool RequiresVirtualMethodDataFlowAnalysis (MethodDefinition method) =>
3135
GetAnnotations (method.DeclaringType).TryGetAnnotation (method, out _);
3236

3337
public bool RequiresDataFlowAnalysis (FieldDefinition field) =>
3438
GetAnnotations (field.DeclaringType).TryGetAnnotation (field, out _);
3539

36-
public bool RequiresDataFlowAnalysis (GenericParameter genericParameter) =>
40+
public bool RequiresGenericArgumentDataFlowAnalysis (GenericParameter genericParameter) =>
3741
GetGenericParameterAnnotation (genericParameter) != DynamicallyAccessedMemberTypes.None;
3842

3943
/// <summary>

src/linker/Linker.Steps/MarkStep.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2622,7 +2622,7 @@ void MarkGenericArguments (IGenericInstance instance)
26222622

26232623
TypeDefinition? argumentTypeDef = MarkType (argument, new DependencyInfo (DependencyKind.GenericArgumentType, instance));
26242624

2625-
if (Annotations.FlowAnnotations.RequiresDataFlowAnalysis (parameter)) {
2625+
if (Annotations.FlowAnnotations.RequiresGenericArgumentDataFlowAnalysis (parameter)) {
26262626
// The only two implementations of IGenericInstance both derive from MemberReference
26272627
Debug.Assert (instance is MemberReference);
26282628

src/linker/Linker/Annotations.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ public void EnqueueVirtualMethod (MethodDefinition method)
678678
if (!method.IsVirtual)
679679
return;
680680

681-
if (FlowAnnotations.RequiresDataFlowAnalysis (method) || HasLinkerAttribute<RequiresUnreferencedCodeAttribute> (method))
681+
if (FlowAnnotations.RequiresVirtualMethodDataFlowAnalysis (method) || HasLinkerAttribute<RequiresUnreferencedCodeAttribute> (method))
682682
VirtualMethodsWithAnnotationsToValidate.Add (method);
683683
}
684684
}

test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeAccessedViaReflection.cs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -534,8 +534,6 @@ class LambdaWhichMarksItself
534534
public static void Test ()
535535
{
536536
var a =
537-
[ExpectedWarning ("IL2118", nameof (LambdaWhichMarksItself), "<Test>",
538-
ProducedBy = ProducedBy.Trimmer)]
539537
() => {
540538
RequiresAllOnT<LambdaWhichMarksItself> ();
541539
};
@@ -548,8 +546,6 @@ class LocalFunctionWhichMarksItself
548546
{
549547
public static void Test ()
550548
{
551-
[ExpectedWarning ("IL2118", nameof (LocalFunctionWhichMarksItself), "<Test>",
552-
ProducedBy = ProducedBy.Trimmer)]
553549
void LocalFunction ()
554550
{
555551
RequiresAllOnT<LocalFunctionWhichMarksItself> ();
@@ -561,7 +557,6 @@ void LocalFunction ()
561557

562558
class IteratorWhichMarksItself
563559
{
564-
[ExpectedWarning ("IL2118", ProducedBy = ProducedBy.Trimmer, CompilerGeneratedCode = true)]
565560
public static IEnumerable<int> Test ()
566561
{
567562
yield return 0;
@@ -574,7 +569,6 @@ public static IEnumerable<int> Test ()
574569

575570
class AsyncWhichMarksItself
576571
{
577-
[ExpectedWarning ("IL2118", ProducedBy = ProducedBy.Trimmer, CompilerGeneratedCode = true)]
578572
public static async void Test ()
579573
{
580574
await MethodAsync ();
@@ -599,8 +593,6 @@ public static void Test ()
599593

600594
class LocalFunctionWhichMarksItselfOnlyAccessedViaReflection
601595
{
602-
[ExpectedWarning ("IL2118", nameof (LocalFunctionWhichMarksItselfOnlyAccessedViaReflection), "<" + nameof (ClassWithLocalFunction.MethodWithLocalFunction) + ">", "LocalFunction",
603-
ProducedBy = ProducedBy.Trimmer)]
604596
public static void Test ()
605597
{
606598
RequiresNonPublicMethodsOnT<ClassWithLocalFunction> ();
@@ -610,8 +602,6 @@ public class ClassWithLocalFunction
610602
{
611603
public static void MethodWithLocalFunction ()
612604
{
613-
[ExpectedWarning ("IL2118", nameof (LocalFunctionWhichMarksItselfOnlyAccessedViaReflection), "<" + nameof (MethodWithLocalFunction) + ">", nameof (LocalFunction),
614-
ProducedBy = ProducedBy.Trimmer)]
615605
static void LocalFunction ()
616606
{
617607
RequiresNonPublicMethodsOnT<ClassWithLocalFunction> ();

0 commit comments

Comments
 (0)