Skip to content

Commit

Permalink
Bump Explicit-layout value types with no fields to at minimum 1 byte …
Browse files Browse the repository at this point in the history
…size. (dotnet#63975)
  • Loading branch information
jkoritzinsky committed Jan 19, 2022
1 parent 6f8d8b2 commit 826e03e
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/coreclr/vm/methodtablebuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
@@ -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"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<Compile Include="explicitStruct_empty.cs" />
</ItemGroup>
</Project>

0 comments on commit 826e03e

Please sign in to comment.