Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJames S. Wang <jjameswwang@gmail.com>2022-09-29 17:18:09 +0300
committerGitHub <noreply@github.com>2022-09-29 17:18:09 +0300
commit48468d194d666a66280fc8abc7e8a47603bcb68f (patch)
tree1646d0e42878d631f8e2a67f6be3f72a725f5951 /src
parente5d2c3e7fe8576c6904c9cc4e47acd9c97817f87 (diff)
Fix value type with static method fails to load (#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
Diffstat (limited to 'src')
-rw-r--r--src/coreclr/vm/methodtablebuilder.cpp16
-rw-r--r--src/tests/baseservices/typeequivalence/pia/PIAContract.csproj9
-rw-r--r--src/tests/baseservices/typeequivalence/pia/Types.cs19
-rw-r--r--src/tests/baseservices/typeequivalence/simple/Simple.cs16
-rw-r--r--src/tests/baseservices/typeequivalence/simple/Simple.csproj1
5 files changed, 53 insertions, 8 deletions
diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp
index 19d1164dc94..ebefaf50e56 100644
--- a/src/coreclr/vm/methodtablebuilder.cpp
+++ b/src/coreclr/vm/methodtablebuilder.cpp
@@ -2659,14 +2659,6 @@ MethodTableBuilder::EnumerateClassMethods()
METHOD_IMPL_TYPE implType;
LPSTR strMethodName;
-#ifdef FEATURE_TYPEEQUIVALENCE
- // TypeEquivalent structs must not have methods
- if (bmtProp->fIsTypeEquivalent && fIsClassValueType)
- {
- BuildMethodTableThrowException(IDS_CLASSLOAD_EQUIVALENTSTRUCTMETHODS);
- }
-#endif
-
//
// Go to the next method and retrieve its attributes.
//
@@ -2686,6 +2678,14 @@ MethodTableBuilder::EnumerateClassMethods()
BuildMethodTableThrowException(IDS_CLASSLOAD_BADFORMAT);
}
+#ifdef FEATURE_TYPEEQUIVALENCE
+ // TypeEquivalent structs must not have non-static methods
+ if (!IsMdStatic(dwMemberAttrs) && bmtProp->fIsTypeEquivalent && fIsClassValueType)
+ {
+ BuildMethodTableThrowException(IDS_CLASSLOAD_EQUIVALENTSTRUCTMETHODS);
+ }
+#endif
+
bool isVtblGap = false;
if (IsMdRTSpecialName(dwMemberAttrs) || IsMdVirtual(dwMemberAttrs) || IsDelegate())
{
diff --git a/src/tests/baseservices/typeequivalence/pia/PIAContract.csproj b/src/tests/baseservices/typeequivalence/pia/PIAContract.csproj
new file mode 100644
index 00000000000..4895e31531d
--- /dev/null
+++ b/src/tests/baseservices/typeequivalence/pia/PIAContract.csproj
@@ -0,0 +1,9 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <OutputType>Library</OutputType>
+ <CLRTestKind>SharedLibrary</CLRTestKind>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="Types.cs" />
+ </ItemGroup>
+</Project>
diff --git a/src/tests/baseservices/typeequivalence/pia/Types.cs b/src/tests/baseservices/typeequivalence/pia/Types.cs
new file mode 100644
index 00000000000..915dc0adca7
--- /dev/null
+++ b/src/tests/baseservices/typeequivalence/pia/Types.cs
@@ -0,0 +1,19 @@
+// 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.InteropServices;
+
+[assembly: PrimaryInteropAssembly(1, 0)]
+
+public struct ValueTypeWithStaticMethod
+{
+ public int F;
+ public static void M() { }
+}
+
+public struct ValueTypeWithInstanceMethod
+{
+ public int F;
+ public void M() { }
+} \ No newline at end of file
diff --git a/src/tests/baseservices/typeequivalence/simple/Simple.cs b/src/tests/baseservices/typeequivalence/simple/Simple.cs
index c79f46ce27b..1d1528f3bf1 100644
--- a/src/tests/baseservices/typeequivalence/simple/Simple.cs
+++ b/src/tests/baseservices/typeequivalence/simple/Simple.cs
@@ -5,6 +5,7 @@ using System;
using System.Linq;
using System.Text;
using System.Reflection;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Xunit;
@@ -253,6 +254,20 @@ public class Simple
}
}
+ [MethodImpl (MethodImplOptions.NoInlining)]
+ private static void TestLoadingValueTypesWithMethod()
+ {
+ Console.WriteLine($"{nameof(TestLoadingValueTypesWithMethod)}");
+ Console.WriteLine($"-- {typeof(ValueTypeWithStaticMethod).Name}");
+ Assert.Throws<TypeLoadException>(() => LoadInvalidType());
+ }
+
+ [MethodImpl (MethodImplOptions.NoInlining)]
+ private static void LoadInvalidType()
+ {
+ Console.WriteLine($"-- {typeof(ValueTypeWithInstanceMethod).Name}");
+ }
+
public static int Main(string[] noArgs)
{
if (!OperatingSystem.IsWindows())
@@ -270,6 +285,7 @@ public class Simple
TestGenericClassNonEquivalence();
TestGenericInterfaceEquivalence();
TestTypeEquivalenceWithTypePunning();
+ TestLoadingValueTypesWithMethod();
}
catch (Exception e)
{
diff --git a/src/tests/baseservices/typeequivalence/simple/Simple.csproj b/src/tests/baseservices/typeequivalence/simple/Simple.csproj
index 37e57397b2c..39d83e32fcc 100644
--- a/src/tests/baseservices/typeequivalence/simple/Simple.csproj
+++ b/src/tests/baseservices/typeequivalence/simple/Simple.csproj
@@ -15,6 +15,7 @@
<ProjectReference Include="../impl/TypeImpl.csproj" />
<ProjectReference Include="../impl/PunningLib.ilproj" />
<ProjectReference Include="$(TestSourceDir)Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" />
+ <ProjectReference Include="../pia/PIAContract.csproj" />
</ItemGroup>
<Import Project="$([MSBuild]::GetPathOfFileAbove(TypeEquivalence.targets))" />
</Project>