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:
authorAndrii Kurdiumov <kant2002@gmail.com>2021-06-03 17:37:55 +0300
committerGitHub <noreply@github.com>2021-06-03 17:37:55 +0300
commitf39ba1a20374ac6af0f2a866a7381192d28b8c37 (patch)
treedcaf644126f86e6d0503a20f89c42927860357d9
parent0f3ea71923fdc93800103ec4d8f59bbe15e2813b (diff)
Handle different dynamic member access for multiple branches (#2076)
This case assume that all code branches should have same minimal dynamic access pattern Was discovered as part of https://github.com/dotnet/runtimelab/issues/1187 Issue happens when 2 code blocks has diferent requirements for dynamic code access, and this produce MergePoint. This case was not handled.
-rw-r--r--src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs18
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/GetInterfaceDataFlow.cs11
2 files changed, 21 insertions, 8 deletions
diff --git a/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs b/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs
index ecf07120d..9459ce1d7 100644
--- a/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs
+++ b/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs
@@ -1777,15 +1777,17 @@ namespace Mono.Linker.Dataflow
}
// Validate that the return value has the correct annotations as per the method return value annotations
- if (returnValueDynamicallyAccessedMemberTypes != 0 && methodReturnValue != null) {
- if (methodReturnValue is LeafValueWithDynamicallyAccessedMemberNode methodReturnValueWithMemberTypes) {
- if (!methodReturnValueWithMemberTypes.DynamicallyAccessedMemberTypes.HasFlag (returnValueDynamicallyAccessedMemberTypes))
+ if (returnValueDynamicallyAccessedMemberTypes != 0) {
+ foreach (var uniqueValue in methodReturnValue.UniqueValues ()) {
+ if (uniqueValue is LeafValueWithDynamicallyAccessedMemberNode methodReturnValueWithMemberTypes) {
+ if (!methodReturnValueWithMemberTypes.DynamicallyAccessedMemberTypes.HasFlag (returnValueDynamicallyAccessedMemberTypes))
+ throw new InvalidOperationException ($"Internal linker error: processing of call from {callingMethodDefinition.GetDisplayName ()} to {calledMethod.GetDisplayName ()} returned value which is not correctly annotated with the expected dynamic member access kinds.");
+ } else if (uniqueValue is SystemTypeValue) {
+ // SystemTypeValue can fullfill any requirement, so it's always valid
+ // The requirements will be applied at the point where it's consumed (passed as a method parameter, set as field value, returned from the method)
+ } else {
throw new InvalidOperationException ($"Internal linker error: processing of call from {callingMethodDefinition.GetDisplayName ()} to {calledMethod.GetDisplayName ()} returned value which is not correctly annotated with the expected dynamic member access kinds.");
- } else if (methodReturnValue is SystemTypeValue) {
- // SystemTypeValue can fullfill any requirement, so it's always valid
- // The requirements will be applied at the point where it's consumed (passed as a method parameter, set as field value, returned from the method)
- } else {
- throw new InvalidOperationException ($"Internal linker error: processing of call from {callingMethodDefinition.GetDisplayName ()} to {calledMethod.GetDisplayName ()} returned value which is not correctly annotated with the expected dynamic member access kinds.");
+ }
}
}
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/GetInterfaceDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/GetInterfaceDataFlow.cs
index 630fc3c14..4a9d8c39f 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/GetInterfaceDataFlow.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/GetInterfaceDataFlow.cs
@@ -66,6 +66,16 @@ namespace Mono.Linker.Tests.Cases.DataFlow
type.GetInterface ("ITestInterface").RequiresAll (); // Warns since only one of the values is guaranteed All
}
+ [ExpectedWarning ("IL2075", nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.Interfaces))]
+ static void TestMergedValues (int p, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type typeWithAll)
+ {
+ Type type = new TestType ().GetType ();
+ if (p == 0) {
+ type = typeWithAll;
+ type.GetInterface ("ITestInterface").RequiresInterfaces ();
+ }
+ }
+
public static void Test ()
{
TestNoAnnotation (typeof (TestType));
@@ -74,6 +84,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
TestWithAll (typeof (TestType));
TestKnownType ();
TestMultipleValues (0, typeof (TestType));
+ TestMergedValues (0, typeof (TestType));
}
}