Skip to content

Commit 48468d1

Browse files
authored
Fix value type with static method fails to load (dotnet#76262)
* Allow static methods if checking type equivalence * Add test for loading value type with static method * Add test in which loading a value type with an instance method should throw a TypeLoadException
1 parent e5d2c3e commit 48468d1

File tree

5 files changed

+53
-8
lines changed

5 files changed

+53
-8
lines changed

src/coreclr/vm/methodtablebuilder.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -2659,14 +2659,6 @@ MethodTableBuilder::EnumerateClassMethods()
26592659
METHOD_IMPL_TYPE implType;
26602660
LPSTR strMethodName;
26612661

2662-
#ifdef FEATURE_TYPEEQUIVALENCE
2663-
// TypeEquivalent structs must not have methods
2664-
if (bmtProp->fIsTypeEquivalent && fIsClassValueType)
2665-
{
2666-
BuildMethodTableThrowException(IDS_CLASSLOAD_EQUIVALENTSTRUCTMETHODS);
2667-
}
2668-
#endif
2669-
26702662
//
26712663
// Go to the next method and retrieve its attributes.
26722664
//
@@ -2686,6 +2678,14 @@ MethodTableBuilder::EnumerateClassMethods()
26862678
BuildMethodTableThrowException(IDS_CLASSLOAD_BADFORMAT);
26872679
}
26882680

2681+
#ifdef FEATURE_TYPEEQUIVALENCE
2682+
// TypeEquivalent structs must not have non-static methods
2683+
if (!IsMdStatic(dwMemberAttrs) && bmtProp->fIsTypeEquivalent && fIsClassValueType)
2684+
{
2685+
BuildMethodTableThrowException(IDS_CLASSLOAD_EQUIVALENTSTRUCTMETHODS);
2686+
}
2687+
#endif
2688+
26892689
bool isVtblGap = false;
26902690
if (IsMdRTSpecialName(dwMemberAttrs) || IsMdVirtual(dwMemberAttrs) || IsDelegate())
26912691
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Library</OutputType>
4+
<CLRTestKind>SharedLibrary</CLRTestKind>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<Compile Include="Types.cs" />
8+
</ItemGroup>
9+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Runtime.InteropServices;
6+
7+
[assembly: PrimaryInteropAssembly(1, 0)]
8+
9+
public struct ValueTypeWithStaticMethod
10+
{
11+
public int F;
12+
public static void M() { }
13+
}
14+
15+
public struct ValueTypeWithInstanceMethod
16+
{
17+
public int F;
18+
public void M() { }
19+
}

src/tests/baseservices/typeequivalence/simple/Simple.cs

+16
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq;
66
using System.Text;
77
using System.Reflection;
8+
using System.Runtime.CompilerServices;
89
using System.Runtime.InteropServices;
910

1011
using Xunit;
@@ -253,6 +254,20 @@ private static unsafe void TestTypeEquivalenceWithTypePunning()
253254
}
254255
}
255256

257+
[MethodImpl (MethodImplOptions.NoInlining)]
258+
private static void TestLoadingValueTypesWithMethod()
259+
{
260+
Console.WriteLine($"{nameof(TestLoadingValueTypesWithMethod)}");
261+
Console.WriteLine($"-- {typeof(ValueTypeWithStaticMethod).Name}");
262+
Assert.Throws<TypeLoadException>(() => LoadInvalidType());
263+
}
264+
265+
[MethodImpl (MethodImplOptions.NoInlining)]
266+
private static void LoadInvalidType()
267+
{
268+
Console.WriteLine($"-- {typeof(ValueTypeWithInstanceMethod).Name}");
269+
}
270+
256271
public static int Main(string[] noArgs)
257272
{
258273
if (!OperatingSystem.IsWindows())
@@ -270,6 +285,7 @@ public static int Main(string[] noArgs)
270285
TestGenericClassNonEquivalence();
271286
TestGenericInterfaceEquivalence();
272287
TestTypeEquivalenceWithTypePunning();
288+
TestLoadingValueTypesWithMethod();
273289
}
274290
catch (Exception e)
275291
{

src/tests/baseservices/typeequivalence/simple/Simple.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<ProjectReference Include="../impl/TypeImpl.csproj" />
1616
<ProjectReference Include="../impl/PunningLib.ilproj" />
1717
<ProjectReference Include="$(TestSourceDir)Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" />
18+
<ProjectReference Include="../pia/PIAContract.csproj" />
1819
</ItemGroup>
1920
<Import Project="$([MSBuild]::GetPathOfFileAbove(TypeEquivalence.targets))" />
2021
</Project>

0 commit comments

Comments
 (0)