Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Koritzinsky <jekoritz@microsoft.com>2021-04-19 23:01:44 +0300
committerGitHub <noreply@github.com>2021-04-19 23:01:44 +0300
commitf6ccab59b40c959c10a28f696b3ec8ba0569fe25 (patch)
tree620c068309c376300451ef6bc56838018887d91f /test/Mono.Linker.Tests.Cases/DataFlow
parent76bcd90110b1c4d65a53b99761ac00e0f6b06b21 (diff)
Support running a basic analysis of generic instantiations created through reflection. (#1955)
Enable a basic analysis for arrays of `System.Type` passed to `Type.MakeGenericType` and `MethodInfo.MakeGenericMethod`. This analysis works for arrays created within the method with a constant size where all array elements are known. This allows for common usages of `Type.MakeGenericType` and `MethodInfo.MakeGenericMethod` that let the compiler implicitly create an array for them (since the parameter is `params`) to get basic analysis. Also enable analysis for ldelem when it's a known array with a known value at a given known index. In combination with #1930, we could also enable this validation for `Expression.Call` on generic types.
Diffstat (limited to 'test/Mono.Linker.Tests.Cases/DataFlow')
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs5
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs190
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs5
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs5
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs5
5 files changed, 179 insertions, 31 deletions
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs
index 6965f80ef..380b72a70 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs
@@ -148,7 +148,12 @@ namespace Mono.Linker.Tests.Cases.DataFlow
{
var array = new object[1];
array[0] = this.GetType ();
+ MakeArrayValuesUnknown (array);
TypeStore._staticTypeWithPublicParameterlessConstructor = (Type) array[0];
+
+ static void MakeArrayValuesUnknown (object[] array)
+ {
+ }
}
private static void RequirePublicParameterlessConstructor (
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs
index 08bb958cd..27d487a3e 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs
@@ -735,6 +735,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow
{
TestNullType ();
TestUnknownInput (null);
+ TestWithUnknownTypeArray (null);
+ TestWithArrayUnknownIndexSet (0);
+ TestWithArrayUnknownLengthSet (1);
TestNoArguments ();
TestWithRequirements ();
@@ -768,6 +771,31 @@ namespace Mono.Linker.Tests.Cases.DataFlow
inputType.MakeGenericType (typeof (TestType));
}
+ [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.MakeGenericType), new Type[] { typeof (Type[]) },
+ messageCode: "IL2055")]
+ static void TestWithUnknownTypeArray (Type[] types)
+ {
+ typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (types);
+ }
+
+ [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.MakeGenericType), new Type[] { typeof (Type[]) },
+ messageCode: "IL2055")]
+ static void TestWithArrayUnknownIndexSet (int indexToSet)
+ {
+ Type[] types = new Type[1];
+ types[indexToSet] = typeof (TestType);
+ typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (types);
+ }
+
+ [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.MakeGenericType), new Type[] { typeof (Type[]) },
+ messageCode: "IL2055")]
+ static void TestWithArrayUnknownLengthSet (int arrayLen)
+ {
+ Type[] types = new Type[arrayLen];
+ types[0] = typeof (TestType);
+ typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (types);
+ }
+
[RecognizedReflectionAccessPattern]
static void TestNoArguments ()
{
@@ -778,8 +806,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
{
}
- [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.MakeGenericType), new Type[] { typeof (Type[]) },
- messageCode: "IL2055")]
+ [RecognizedReflectionAccessPattern]
static void TestWithRequirements ()
{
// Currently this is not analyzable since we don't track array elements.
@@ -787,16 +814,14 @@ namespace Mono.Linker.Tests.Cases.DataFlow
typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (typeof (TestType));
}
- [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.MakeGenericType), new Type[] { typeof (Type[]) },
- messageCode: "IL2055")]
+ [RecognizedReflectionAccessPattern]
static void TestWithRequirementsFromParam (
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] Type type)
{
typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (type);
}
- [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.MakeGenericType), new Type[] { typeof (Type[]) },
- messageCode: "IL2055")]
+ [RecognizedReflectionAccessPattern]
static void TestWithRequirementsFromGenericParam<
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> ()
{
@@ -823,8 +848,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
{
}
- [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.MakeGenericType), new Type[] { typeof (Type[]) },
- messageCode: "IL2055")]
+ [RecognizedReflectionAccessPattern]
static void TestWithMultipleArgumentsWithRequirements ()
{
typeof (GenericWithMultipleArgumentsWithRequirements<,>).MakeGenericType (typeof (TestType), typeof (TestType));
@@ -836,8 +860,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
{
}
- [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.MakeGenericType), new Type[] { typeof (Type[]) },
- messageCode: "IL2055")]
+ [RecognizedReflectionAccessPattern]
static void TestWithNewConstraint ()
{
typeof (GenericWithNewConstraint<>).MakeGenericType (typeof (TestType));
@@ -847,8 +870,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
{
}
- [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.MakeGenericType), new Type[] { typeof (Type[]) },
- messageCode: "IL2055")]
+ [RecognizedReflectionAccessPattern]
static void TestWithStructConstraint ()
{
typeof (GenericWithStructConstraint<>).MakeGenericType (typeof (TestType));
@@ -858,8 +880,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
{
}
- [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.MakeGenericType), new Type[] { typeof (Type[]) },
- messageCode: "IL2055")]
+ [RecognizedReflectionAccessPattern]
static void TestWithUnmanagedConstraint ()
{
typeof (GenericWithUnmanagedConstraint<>).MakeGenericType (typeof (TestType));
@@ -881,8 +902,13 @@ namespace Mono.Linker.Tests.Cases.DataFlow
public static void Test ()
{
TestNullMethod ();
- TestUnknownInput (null);
+ TestUnknownMethod (null);
TestUnknownMethodButNoTypeArguments (null);
+ TestWithUnknownTypeArray (null);
+ TestWithArrayUnknownIndexSet (0);
+ TestWithArrayUnknownIndexSetByRef (0);
+ TestWithArrayUnknownLengthSet (1);
+ TestWithArrayPassedToAnotherMethod ();
TestWithNoArguments ();
TestWithRequirements ();
@@ -891,6 +917,11 @@ namespace Mono.Linker.Tests.Cases.DataFlow
TestWithRequirementsViaRuntimeMethod ();
TestWithRequirementsButNoTypeArguments ();
+ TestWithMultipleKnownGenericParameters ();
+ TestWithOneUnknownGenericParameter (null);
+ TestWithPartiallyInitializedGenericTypeArray ();
+ TestWithConditionalGenericTypeSet (true);
+
TestWithNoRequirements ();
TestWithNoRequirementsFromParam (null);
TestWithNoRequirementsViaRuntimeMethod ();
@@ -911,7 +942,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
[UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) },
messageCode: "IL2060")]
- static void TestUnknownInput (MethodInfo mi)
+ static void TestUnknownMethod (MethodInfo mi)
{
mi.MakeGenericMethod (typeof (TestType));
}
@@ -924,6 +955,61 @@ namespace Mono.Linker.Tests.Cases.DataFlow
mi.MakeGenericMethod (Type.EmptyTypes);
}
+ [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) },
+ messageCode: "IL2060")]
+ static void TestWithUnknownTypeArray (Type[] types)
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
+ .MakeGenericMethod (types);
+ }
+
+ [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) },
+ messageCode: "IL2060")]
+ static void TestWithArrayUnknownIndexSet (int indexToSet)
+ {
+ Type[] types = new Type[1];
+ types[indexToSet] = typeof (TestType);
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
+ .MakeGenericMethod (types);
+ }
+
+ [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) },
+ messageCode: "IL2060")]
+ static void TestWithArrayUnknownIndexSetByRef (int indexToSet)
+ {
+ Type[] types = new Type[1];
+ types[0] = typeof (TestType);
+ ref Type t = ref types[indexToSet];
+ t = typeof (TestType);
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
+ .MakeGenericMethod (types);
+ }
+
+ [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) },
+ messageCode: "IL2060")]
+ static void TestWithArrayUnknownLengthSet (int arrayLen)
+ {
+ Type[] types = new Type[arrayLen];
+ types[0] = typeof (TestType);
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
+ .MakeGenericMethod (types);
+ }
+
+ static void MethodThatTakesArrayParameter (Type[] types)
+ {
+ }
+
+ [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) },
+ messageCode: "IL2060")]
+ static void TestWithArrayPassedToAnotherMethod ()
+ {
+ Type[] types = new Type[1];
+ types[0] = typeof (TestType);
+ MethodThatTakesArrayParameter (types);
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
+ .MakeGenericMethod (types);
+ }
+
[RecognizedReflectionAccessPattern]
static void TestWithNoArguments ()
{
@@ -935,16 +1021,14 @@ namespace Mono.Linker.Tests.Cases.DataFlow
{
}
- [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) },
- messageCode: "IL2060")]
+ [RecognizedReflectionAccessPattern]
static void TestWithRequirements ()
{
typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
.MakeGenericMethod (typeof (TestType));
}
- [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) },
- messageCode: "IL2060")]
+ [RecognizedReflectionAccessPattern]
static void TestWithRequirementsFromParam (
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] Type type)
{
@@ -959,8 +1043,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow
.MakeGenericMethod (typeof (T));
}
- [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) },
- messageCode: "IL2060")]
+
+ [RecognizedReflectionAccessPattern]
static void TestWithRequirementsViaRuntimeMethod ()
{
typeof (MakeGenericMethod).GetRuntimeMethod (nameof (GenericWithRequirements), Type.EmptyTypes)
@@ -971,7 +1055,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow
messageCode: "IL2060")]
static void TestWithRequirementsButNoTypeArguments ()
{
- // Linker could figure out that this is not a problem, but it's not worth the complexity, since this will always throw at runtime
typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
.MakeGenericMethod (Type.EmptyTypes);
}
@@ -981,6 +1064,54 @@ namespace Mono.Linker.Tests.Cases.DataFlow
}
[RecognizedReflectionAccessPattern]
+ static void TestWithMultipleKnownGenericParameters ()
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericMultipleParameters), BindingFlags.Static)
+ .MakeGenericMethod (typeof (TestType), typeof (TestType), typeof (TestType));
+ }
+
+ [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) },
+ messageCode: "IL2060")]
+ static void TestWithOneUnknownGenericParameter (Type[] types)
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericMultipleParameters), BindingFlags.Static)
+ .MakeGenericMethod (typeof (TestType), typeof (TestStruct), types[0]);
+ }
+
+ [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) },
+ messageCode: "IL2060")]
+ static void TestWithPartiallyInitializedGenericTypeArray ()
+ {
+ Type[] types = new Type[3];
+ types[0] = typeof (TestType);
+ types[1] = typeof (TestStruct);
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericMultipleParameters), BindingFlags.Static)
+ .MakeGenericMethod (types);
+ }
+
+ [RecognizedReflectionAccessPattern]
+ static void TestWithConditionalGenericTypeSet (bool thirdParameterIsStruct)
+ {
+ Type[] types = new Type[3];
+ types[0] = typeof (TestType);
+ types[1] = typeof (TestStruct);
+ if (thirdParameterIsStruct) {
+ types[2] = typeof (TestStruct);
+ } else {
+ types[2] = typeof (TestType);
+ }
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericMultipleParameters), BindingFlags.Static)
+ .MakeGenericMethod (types);
+ }
+
+ public static void GenericMultipleParameters<
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T,
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] U,
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] V> ()
+ {
+ }
+
+ [RecognizedReflectionAccessPattern]
static void TestWithNoRequirements ()
{
typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNoRequirements), BindingFlags.Static)
@@ -1005,8 +1136,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow
{
}
- [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) },
- messageCode: "IL2060")]
+
+ [RecognizedReflectionAccessPattern]
static void TestWithMultipleArgumentsWithRequirements ()
{
typeof (MakeGenericMethod).GetMethod (nameof (GenericWithMultipleArgumentsWithRequirements), BindingFlags.Static | BindingFlags.NonPublic)
@@ -1019,8 +1150,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
{
}
- [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) },
- messageCode: "IL2060")]
+ [RecognizedReflectionAccessPattern]
static void TestWithNewConstraint ()
{
typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNewConstraint), BindingFlags.Static | BindingFlags.NonPublic)
@@ -1032,8 +1162,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
var t = new T ();
}
- [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) },
- messageCode: "IL2060")]
+ [RecognizedReflectionAccessPattern]
static void TestWithStructConstraint ()
{
typeof (MakeGenericMethod).GetMethod (nameof (GenericWithStructConstraint), BindingFlags.Static | BindingFlags.NonPublic)
@@ -1045,8 +1174,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
var t = new T ();
}
- [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) },
- messageCode: "IL2060")]
+ [RecognizedReflectionAccessPattern]
static void TestWithUnmanagedConstraint ()
{
typeof (MakeGenericMethod).GetMethod (nameof (GenericWithUnmanagedConstraint), BindingFlags.Static | BindingFlags.NonPublic)
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs
index 2897c4705..fe11b6b03 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs
@@ -161,7 +161,12 @@ namespace Mono.Linker.Tests.Cases.DataFlow
{
var array = new object[1];
array[0] = this.GetType ();
+ MakeArrayValuesUnknown (array);
RequirePublicParameterlessConstructor ((Type) array[0]);
+
+ static void MakeArrayValuesUnknown (object[] array)
+ {
+ }
}
[RecognizedReflectionAccessPattern]
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs
index f66a25e74..c0925a264 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs
@@ -126,7 +126,12 @@ namespace Mono.Linker.Tests.Cases.DataFlow
{
var array = new object[1];
array[0] = this.GetType ();
+ MakeArrayValuesUnknown (array);
return (Type) array[0];
+
+ static void MakeArrayValuesUnknown (object[] array)
+ {
+ }
}
[UnrecognizedReflectionAccessPattern (typeof (MethodReturnParameterDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2072")]
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs
index 9dc4813b8..a8bfbed1f 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs
@@ -100,7 +100,12 @@ namespace Mono.Linker.Tests.Cases.DataFlow
{
var array = new object[1];
array[0] = array.GetType ();
+ MakeArrayValuesUnknown (array);
((MethodThisDataFlowTypeTest) array[0]).RequireThisNonPublicMethods ();
+
+ static void MakeArrayValuesUnknown (object[] array)
+ {
+ }
}
[UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (MethodThisDataFlowTypeTest.RequireThisPublicMethods), new Type[] { },