Fix Mono default interface methods with protected virtual class methods (#82577)
authorBill Holmes <bill.holmes@unity3d.com>
Fri, 24 Feb 2023 19:15:32 +0000 (14:15 -0500)
committerGitHub <noreply@github.com>
Fri, 24 Feb 2023 19:15:32 +0000 (13:15 -0600)
Fixing the METHOD_ATTRIBUTE_PUBLIC flag check on the class method for
check_interface_method_override.

src/mono/mono/metadata/class-setup-vtable.c
src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github82577.cs [new file with mode: 0644]
src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github82577.csproj [new file with mode: 0644]

index 19c32f2..505bf06 100644 (file)
@@ -514,7 +514,7 @@ check_interface_method_override (MonoClass *klass, MonoMethod *im, MonoMethod *c
        gboolean variant_itf = (flags & MONO_ITF_OVERRIDE_VARIANT_ITF) != 0;
        MonoMethodSignature *cmsig, *imsig;
        if (strcmp (im->name, cm->name) == 0) {
-               if (! (cm->flags & METHOD_ATTRIBUTE_PUBLIC)) {
+               if ((cm->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PUBLIC) {
                        TRACE_INTERFACE_VTABLE (printf ("[PUBLIC CHECK FAILED]"));
                        return FALSE;
                }
diff --git a/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github82577.cs b/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github82577.cs
new file mode 100644 (file)
index 0000000..c7a0f9b
--- /dev/null
@@ -0,0 +1,38 @@
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+
+
+class Program
+{
+    static int Main()
+    {
+       int ret;
+       ret = (new TestClass() as ITestInterface).PublicInterfaceProtectedVirtualClass();
+       if (ret != 100) return ret;
+
+       ret = (new TestClass() as ITestInterface).PublicInterfaceProtectedClass();
+       if (ret != 100) return ret;
+
+       ret = (new TestClass() as ITestInterface).PublicInterfacePublicClass();
+       if (ret != 100) return ret;
+
+       return ret;
+    }
+}
+
+public interface ITestInterface
+{
+    public int PublicInterfaceProtectedVirtualClass()=> 100;
+    public int PublicInterfaceProtectedClass()=> 100;
+    public int PublicInterfacePublicClass()=> 3;
+}
+
+public class TestClass : ITestInterface
+{
+    protected virtual int PublicInterfaceProtectedVirtualClass()=> 1;
+    protected int PublicInterfaceProtectedClass()=> 2;
+    public int PublicInterfacePublicClass()=> 100;
+}
+
+
diff --git a/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github82577.csproj b/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github82577.csproj
new file mode 100644 (file)
index 0000000..42c7a9e
--- /dev/null
@@ -0,0 +1,9 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <OutputType>Exe</OutputType>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="$(MSBuildProjectName).cs" />
+  </ItemGroup>
+</Project>