diff --git a/src/coreclr/dlls/mscorrc/mscorrc.rc b/src/coreclr/dlls/mscorrc/mscorrc.rc
index e85b88fcdd07aa..0fed12722a1139 100644
--- a/src/coreclr/dlls/mscorrc/mscorrc.rc
+++ b/src/coreclr/dlls/mscorrc/mscorrc.rc
@@ -308,6 +308,7 @@ BEGIN
IDS_CLASSLOAD_INLINE_ARRAY_FIELD_COUNT "InlineArrayAttribute requires that the target type has a single instance field. Type: '%1'. Assembly: '%2'."
IDS_CLASSLOAD_INLINE_ARRAY_LENGTH "InlineArrayAttribute requires that the length argument is greater than 0. Type: '%1'. Assembly: '%2'."
IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT "InlineArrayAttribute cannot be applied to a type with explicit layout. Type: '%1'. Assembly: '%2'."
+ IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT_SIZE "InlineArrayAttribute cannot be applied to a type with explicit size. Type: '%1'. Assembly: '%2'."
IDS_CLASSLOAD_BYREF_OF_BYREF "Could not create a ByRef of a ByRef. Type: '%1'. Assembly: '%2'."
IDS_CLASSLOAD_POINTER_OF_BYREF "Could not create a pointer to a ByRef. Type: '%1'. Assembly: '%2'."
diff --git a/src/coreclr/dlls/mscorrc/resource.h b/src/coreclr/dlls/mscorrc/resource.h
index 397efa1f2ae768..f7ae1dea4a6259 100644
--- a/src/coreclr/dlls/mscorrc/resource.h
+++ b/src/coreclr/dlls/mscorrc/resource.h
@@ -160,6 +160,8 @@
#define IDS_CLASSLOAD_BYREF_OF_BYREF 0x17af
#define IDS_CLASSLOAD_POINTER_OF_BYREF 0x17b0
+#define IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT_SIZE 0x17b1
+
#define IDS_INVALID_REDIM 0x17c3
#define IDS_INVALID_PINVOKE_CALLCONV 0x17c4
#define IDS_CLASSLOAD_NSTRUCT_EXPLICIT_OFFSET 0x17c7
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/TypeLoaderExceptionHelper.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/TypeLoaderExceptionHelper.cs
index 70d17bb96989d7..e837f7c6c96518 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/TypeLoaderExceptionHelper.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/TypeLoaderExceptionHelper.cs
@@ -92,6 +92,8 @@ private static string GetFormatString(ExceptionStringID id)
return SR.ClassLoad_InlineArrayLength;
case ExceptionStringID.ClassLoadInlineArrayExplicit:
return SR.ClassLoad_InlineArrayExplicit;
+ case ExceptionStringID.ClassLoadInlineArrayExplicitSize:
+ return SR.ClassLoad_InlineArrayExplicitSize;
case ExceptionStringID.InvalidProgramDefault:
return SR.InvalidProgram_Default;
case ExceptionStringID.InvalidProgramSpecific:
diff --git a/src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs b/src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs
index 923ec0da4316fb..97363c783f8a3e 100644
--- a/src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs
@@ -19,6 +19,7 @@ public enum ExceptionStringID
ClassLoadInlineArrayFieldCount,
ClassLoadInlineArrayLength,
ClassLoadInlineArrayExplicit,
+ ClassLoadInlineArrayExplicitSize,
// MissingMethodException
MissingMethod,
diff --git a/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs b/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs
index 107d8dbffb87c4..604f76cd09442f 100644
--- a/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs
@@ -510,6 +510,12 @@ private static void AdjustForInlineArray(
ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadInlineArrayFieldCount, type);
}
+ var layoutMetadata = type.GetClassLayout();
+ if (layoutMetadata.Size != 0)
+ {
+ ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadInlineArrayExplicitSize, type);
+ }
+
if (!instanceByteSizeAndAlignment.Size.IsIndeterminate)
{
long size = instanceByteSizeAndAlignment.Size.AsInt;
diff --git a/src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx b/src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx
index 6a2f012e012586..1ce5dcbd5e3333 100644
--- a/src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx
+++ b/src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx
@@ -138,6 +138,9 @@
InlineArrayAttribute cannot be applied to a type with explicit layout. Type: '{0}'. Assembly: '{1}'.'
+
+ InlineArrayAttribute cannot be applied to a type with explicit size. Type: '{0}'. Assembly: '{1}'.'
+
Array of type '{0}' from assembly '{1}' cannot be created because base value type is too large
diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp
index 66d9199dcfc410..f8628b4197edc3 100644
--- a/src/coreclr/vm/methodtablebuilder.cpp
+++ b/src/coreclr/vm/methodtablebuilder.cpp
@@ -1771,6 +1771,12 @@ MethodTableBuilder::BuildMethodTableThrowing(
{
BuildMethodTableThrowException(IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT);
}
+
+ ULONG classSize;
+ if (SUCCEEDED(GetMDImport()->GetClassTotalSize(cl, &classSize)) && classSize != 0)
+ {
+ BuildMethodTableThrowException(IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT_SIZE);
+ }
}
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
index 4b45d710bc3fd6..497a524ed303fa 100644
--- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
+++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
@@ -4202,6 +4202,9 @@
InlineArrayAttribute cannot be applied to a type with explicit layout. Type: '{0}'. Assembly: '{1}'.
+
+ InlineArrayAttribute cannot be applied to a type with explicit size. Type: '{0}'. Assembly: '{1}'.
+
Could not load type '{0}' from assembly '{1}' because generic types cannot have explicit layout.
diff --git a/src/mono/mono/metadata/class-init.c b/src/mono/mono/metadata/class-init.c
index 6b8daf900f7494..52f108fc7cc9a0 100644
--- a/src/mono/mono/metadata/class-init.c
+++ b/src/mono/mono/metadata/class-init.c
@@ -317,6 +317,13 @@ mono_class_setup_fields (MonoClass *klass)
if (explicit_size)
instance_size += real_size;
+ if (explicit_size && real_size != 0 && m_class_is_inlinearray (klass)) {
+ if (mono_get_runtime_callbacks ()->mono_class_set_deferred_type_load_failure_callback)
+ mono_get_runtime_callbacks ()->mono_class_set_deferred_type_load_failure_callback (klass, "Inline array must not have explicit size.");
+ else
+ mono_class_set_type_load_failure (klass, "Inline array must not have explicit size.");
+ }
+
/*
* This function can recursively call itself.
* Prevent infinite recursion by using a list in TLS.
diff --git a/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.cs b/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.cs
index daa35af75c7502..0171c97429de56 100644
--- a/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.cs
+++ b/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.cs
@@ -22,6 +22,45 @@ public static void Explicit_Fails()
});
}
+ [Fact]
+ public static void ExplicitSize_FailsInSequential()
+ {
+ Console.WriteLine($"{nameof(ExplicitSize_FailsInSequential)}...");
+
+ Assert.Throws(() => { var t = typeof(ExplicitSize); });
+
+ Assert.Throws(() =>
+ {
+ return new ExplicitSize();
+ });
+ }
+
+ [Fact]
+ public static void ExplicitSize_FailsInAuto()
+ {
+ Console.WriteLine($"{nameof(ExplicitSize_FailsInAuto)}...");
+
+ Assert.Throws(() => { var t = typeof(ExplicitSizeAuto); });
+
+ Assert.Throws(() =>
+ {
+ return sizeof(ExplicitSizeAuto);
+ });
+ }
+
+ [Fact]
+ public static void ExplicitSize_FailsInGeneric()
+ {
+ Console.WriteLine($"{nameof(ExplicitSize_FailsInGeneric)}...");
+
+ Assert.Throws(() => { var t = typeof(ExplicitSizeGeneric); });
+
+ Assert.Throws(() =>
+ {
+ return new ExplicitSizeGeneric();
+ });
+ }
+
[Fact]
public static void ZeroLength_Fails()
{
diff --git a/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.csproj b/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.csproj
index 098ebbb26a691a..c9e8dc0015fade 100644
--- a/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.csproj
+++ b/src/tests/Loader/classloader/InlineArray/InlineArrayInvalid.csproj
@@ -5,6 +5,7 @@
true
false
+ 0
diff --git a/src/tests/Loader/classloader/InlineArray/InvalidCSharpInlineArray.il b/src/tests/Loader/classloader/InlineArray/InvalidCSharpInlineArray.il
index 47e3e0a53d725a..ca71640f41fc37 100644
--- a/src/tests/Loader/classloader/InlineArray/InvalidCSharpInlineArray.il
+++ b/src/tests/Loader/classloader/InlineArray/InvalidCSharpInlineArray.il
@@ -14,6 +14,39 @@
.field [0] public valuetype [System.Runtime]System.Guid Guid
}
+.class public sequential ansi sealed beforefieldinit ExplicitSize
+ extends [System.Runtime]System.ValueType
+{
+ .custom instance void [System.Runtime]System.Runtime.CompilerServices.InlineArrayAttribute::.ctor(int32) = (
+ 01 00 01 00 00 00 00 00
+ )
+
+ .size 256
+ .field [0] public valuetype [System.Runtime]System.Guid Guid
+}
+
+.class public auto ansi sealed beforefieldinit ExplicitSizeAuto
+ extends [System.Runtime]System.ValueType
+{
+ .custom instance void [System.Runtime]System.Runtime.CompilerServices.InlineArrayAttribute::.ctor(int32) = (
+ 01 00 01 00 00 00 00 00
+ )
+
+ .size 256
+ .field [0] public valuetype [System.Runtime]System.Guid Guid
+}
+
+.class public auto ansi sealed beforefieldinit ExplicitSizeGeneric`1
+ extends [System.Runtime]System.ValueType
+{
+ .custom instance void [System.Runtime]System.Runtime.CompilerServices.InlineArrayAttribute::.ctor(int32) = (
+ 01 00 01 00 00 00 00 00
+ )
+
+ .size 256
+ .field [0] public valuetype [System.Runtime]System.Guid Guid
+}
+
.class public sequential ansi sealed beforefieldinit ZeroLength
extends [System.Runtime]System.ValueType
{