From 6087adb2aa3cd803c12ac03bdca5d3652beab9d1 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Wed, 1 Sep 2021 15:53:55 -0400 Subject: [PATCH 1/2] [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 --- src/mono/mono/mini/mini-trampolines.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/mini/mini-trampolines.c b/src/mono/mono/mini/mini-trampolines.c index 36fb6ca4d84b5c..07a50524a0feb2 100644 --- a/src/mono/mono/mini/mini-trampolines.c +++ b/src/mono/mono/mini/mini-trampolines.c @@ -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); From bd0ccd2e16b4fd3f8da541e7d729813111eb8e5b Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Wed, 1 Sep 2021 16:31:24 -0400 Subject: [PATCH 2/2] Add regression test --- .../regressions/github58394.cs | 47 +++++++++++++++++++ .../regressions/github58394.csproj | 11 +++++ 2 files changed, 58 insertions(+) create mode 100644 src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github58394.cs create mode 100644 src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github58394.csproj diff --git a/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github58394.cs b/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github58394.cs new file mode 100644 index 00000000000000..ee94e5422908dc --- /dev/null +++ b/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github58394.cs @@ -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(); + } + } + + interface IFoo + { + int Crash() => 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 index 00000000000000..aab61d4e4497b8 --- /dev/null +++ b/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github58394.csproj @@ -0,0 +1,11 @@ + + + true + Exe + BuildAndRun + 0 + + + + +