[release/6.0] [mini] Don't add unbox tramopline on generic DIM calls (#58585)
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Tue, 7 Sep 2021 17:35:56 +0000 (10:35 -0700)
committerGitHub <noreply@github.com>
Tue, 7 Sep 2021 17:35:56 +0000 (10:35 -0700)
* [mini] Don't add unbox tramopline on generic DIM calls

Don't unbox a valuetype `this` if the generic method is a DIM

Fixes https://github.com/dotnet/runtime/issues/58394

* Add regression test

Co-authored-by: Aleksey Kliger <alklig@microsoft.com>
src/mono/mono/mini/mini-trampolines.c
src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github58394.cs [new file with mode: 0644]
src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github58394.csproj [new file with mode: 0644]

index 36fb6ca..07a5052 100644 (file)
@@ -632,11 +632,13 @@ common_call_trampoline (host_mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTa
                return NULL;
 
        if (generic_virtual || variant_iface) {
-               if (m_class_is_valuetype (vt->klass)) /*FIXME is this required variant iface?*/
+               if (m_class_is_valuetype (vt->klass)  && !mini_method_is_default_method (m)) /*FIXME is this required variant iface?*/
                        need_unbox_tramp = TRUE;
        } else if (orig_vtable_slot) {
-               if (m_class_is_valuetype (m->klass))
+               if (m_class_is_valuetype (m->klass)) {
+                       g_assert (!mini_method_is_default_method (m));
                        need_unbox_tramp = TRUE;
+               }
        }
 
        addr = mini_add_method_trampoline (m, compiled_method, need_rgctx_tramp, need_unbox_tramp);
diff --git a/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github58394.cs b/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github58394.cs
new file mode 100644 (file)
index 0000000..ee94e54
--- /dev/null
@@ -0,0 +1,47 @@
+// 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;
+
+namespace GenericDimValuetypeBug
+{
+    class Program
+    {
+        static int Main()
+        {
+            if (RunOne() != 17)
+                return 1;
+            if (RunTwo() != 23)
+                return 2;
+            return 100;
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static int RunOne()
+        {
+            return (new Foo() { x = 17 } as IFoo).NoCrash();
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        public static int RunTwo()
+        {
+            return (new Foo() { x = 23 } as IFoo).Crash<int>();
+        }
+    }
+
+    interface IFoo
+    {
+        int Crash<T>() => Bla();
+
+        int NoCrash() => Bla();
+
+        int Bla();
+    }
+
+    struct Foo: IFoo
+    {
+        public int x;
+        public int Bla() => x;
+    }
+}
diff --git a/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github58394.csproj b/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github58394.csproj
new file mode 100644 (file)
index 0000000..aab61d4
--- /dev/null
@@ -0,0 +1,11 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <OutputType>Exe</OutputType>
+    <CLRTestKind>BuildAndRun</CLRTestKind>
+    <CLRTestPriority>0</CLRTestPriority>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="$(MSBuildProjectName).cs" />
+  </ItemGroup>
+</Project>