diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs index 9979a0deb8cc43..53e9b8727ded76 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs @@ -311,6 +311,22 @@ protected override void GetMetadataDependenciesDueToReflectability(ref Dependenc } } + if (type.IsArray) + { + // Array.Initialize needs the default constructor of the element type to be reflectable + // for value types with a public parameterless constructor. + TypeDesc elementType = ((ArrayType)type).ElementType; + if (elementType.IsValueType) + { + MethodDesc defaultConstructor = elementType.GetDefaultConstructor(); + if (defaultConstructor is not null && !IsReflectionBlocked(defaultConstructor)) + { + dependencies ??= new DependencyList(); + dependencies.Add(factory.ReflectedMethod(defaultConstructor.GetCanonMethodTarget(CanonicalFormKind.Specific)), "Array.Initialize needs default constructor"); + } + } + } + MetadataType mdType = type as MetadataType; ModuleDesc module = mdType?.Module; if (module != null && !_rootEntireAssembliesExaminedModules.Contains(module)) diff --git a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs index 10a21b4d59e236..c361b46a785d3f 100644 --- a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs +++ b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs @@ -99,6 +99,7 @@ private static int Main() TestGenericAttributesOnEnum.Run(); TestLdtokenWithSignaturesDifferingInModifiers.Run(); TestActivatingThingsInSignature.Run(); + TestArrayInitialize.Run(); TestDelegateInvokeFromEvent.Run(); return 100; @@ -3004,6 +3005,37 @@ public struct MyStruct; public struct MyArrayElementStruct; } + class TestArrayInitialize + { + static int s_constructorCallCount = 0; + + public struct ValueTypeWithConstructor + { + public ValueTypeWithConstructor() + { + s_constructorCallCount++; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Array AllocateArray() => new ValueTypeWithConstructor[3]; + + public static void Run() + { + Console.WriteLine(nameof(TestArrayInitialize)); + + s_constructorCallCount = 0; + + // Create an array and call Initialize + var array = AllocateArray(); + array.Initialize(); + + // Verify that the constructor was called for each element + if (s_constructorCallCount != 3) + throw new Exception($"Expected constructor to be called 3 times, but was called {s_constructorCallCount} times"); + } + } + class TestDelegateInvokeFromEvent { class MyClass