diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index 694e03cca35f2..68d11affa4351 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -8648,6 +8648,14 @@ MethodTableBuilder::HandleExplicitLayout( BuildMethodTableThrowException(IDS_CLASSLOAD_GENERAL); } } + + if (!numInstanceFieldBytes.IsOverflow() && numInstanceFieldBytes.Value() == 0) + { + // If we calculate a 0-byte size here, we should have also calculated a 0-byte size + // in the initial layout algorithm. + _ASSERTE(GetLayoutInfo()->IsZeroSized()); + numInstanceFieldBytes = S_UINT32(1); + } } // The GC requires that all valuetypes containing orefs be sized to a multiple of TARGET_POINTER_SIZE. diff --git a/src/tests/Loader/classloader/explicitlayout/Regressions/empty/explicitStruct_empty.cs b/src/tests/Loader/classloader/explicitlayout/Regressions/empty/explicitStruct_empty.cs new file mode 100644 index 0000000000000..1de3b4442c7fb --- /dev/null +++ b/src/tests/Loader/classloader/explicitlayout/Regressions/empty/explicitStruct_empty.cs @@ -0,0 +1,60 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Xunit; + +[StructLayout(LayoutKind.Explicit)] +public struct S +{ +} + +[StructLayout(LayoutKind.Explicit)] +public struct S2 +{ +} + +[StructLayout(LayoutKind.Explicit)] +public class C +{ +} + +[StructLayout(LayoutKind.Explicit)] +public class C2 +{ +} + +public class Test_explicitStruct_empty +{ + // Mark as no-inlining so any test failures will show the right stack trace even after + // we consolidate test assemblies. + [Fact] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void EmptyExplicitStructCanBeLoadedAndCreated() + { + S s = new S(); + } + + [Fact] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void EmptyExplicitStructCanBeLoadedAndCreatedThroughReflection() + { + object s = Activator.CreateInstance(Type.GetType("S2")); + } + + [Fact] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void EmptyExplicitClassCanBeLoadedAndCreated() + { + C c = new C(); + } + + [Fact] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void EmptyExplicitClassCanBeLoadedAndCreatedThroughReflection() + { + object c = Activator.CreateInstance(Type.GetType("C2")); + } +} diff --git a/src/tests/Loader/classloader/explicitlayout/Regressions/empty/explicitStruct_empty.csproj b/src/tests/Loader/classloader/explicitlayout/Regressions/empty/explicitStruct_empty.csproj new file mode 100644 index 0000000000000..a304092ec069b --- /dev/null +++ b/src/tests/Loader/classloader/explicitlayout/Regressions/empty/explicitStruct_empty.csproj @@ -0,0 +1,5 @@ + + + + +