From 847c74d16f06f0a5e41ccaa69c8b731b2c01d85c Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 14 Jul 2021 22:46:19 +0000 Subject: [PATCH 1/2] Fix Activator.CreateInstance case When no ctor parameters are passed, and non-public binding flags are used, we only need to require parameterless constructors. --- src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs b/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs index 18d2df077196..515b1345fe21 100644 --- a/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs +++ b/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs @@ -1596,10 +1596,10 @@ public override bool HandleCall (MethodBody callingMethodBody, MethodReference c var requiredMemberTypes = GetDynamicallyAccessedMemberTypesFromBindingFlagsForConstructors (bindingFlags); // Special case the public parameterless constructor if we know that there are 0 args passed in - if (ctorParameterCount == 0 && - requiredMemberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicConstructors) && - !requiredMemberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicConstructors)) - requiredMemberTypes = DynamicallyAccessedMemberTypes.PublicParameterlessConstructor; + if (ctorParameterCount == 0 && requiredMemberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicConstructors)) { + requiredMemberTypes &= ~DynamicallyAccessedMemberTypes.PublicConstructors; + requiredMemberTypes |= DynamicallyAccessedMemberTypes.PublicParameterlessConstructor; + } RequireDynamicallyAccessedMembers (ref reflectionContext, requiredMemberTypes, value, calledMethod.Parameters[0]); } From bec84fa3594b60bd82d5510301f6dff1c7eef239 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Thu, 15 Jul 2021 01:40:05 +0000 Subject: [PATCH 2/2] Add test --- .../Reflection/ActivatorCreateInstance.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/Mono.Linker.Tests.Cases/Reflection/ActivatorCreateInstance.cs b/test/Mono.Linker.Tests.Cases/Reflection/ActivatorCreateInstance.cs index bd21af5bcbee..e2b019e39b2e 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/ActivatorCreateInstance.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/ActivatorCreateInstance.cs @@ -55,6 +55,7 @@ public static void Main () TestNullArgsOnKnownType (); TestNullArgsOnAnnotatedType (typeof (TestType)); TestNullArgsNonPublicOnly (typeof (TestType)); + TestNullArgsNonPublicWithNonPublicAnnotation (typeof (TestType)); CreateInstanceWithGetTypeFromHierarchy.Test (); } @@ -532,6 +533,15 @@ private static void TestNullArgsNonPublicOnly ( Activator.CreateInstance (type, BindingFlags.NonPublic | BindingFlags.Instance, null, null, CultureInfo.InvariantCulture); } + [Kept] + [ExpectedNoWarnings] + private static void TestNullArgsNonPublicWithNonPublicAnnotation ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.NonPublicConstructors), + KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] Type type) + { + Activator.CreateInstance (type, nonPublic: true); + } + [Kept] class CreateInstanceWithGetTypeFromHierarchy {