From be8bb4212b7a88b50c6b4074aab677f666f71e5a Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Wed, 28 Feb 2024 15:52:28 -0500 Subject: [PATCH 01/16] Add basic ref struct support for generic parameter --- src/mono/mono/metadata/class-init.c | 2 +- src/mono/mono/metadata/class.c | 2 -- src/mono/mono/metadata/object-internals.h | 21 ++++++++++--------- src/mono/mono/metadata/verify.c | 3 +++ .../ByRefLike/GenericTypeSubstitution.cs | 2 -- .../generics/ByRefLike/InvalidCSharp.ilproj | 1 - .../generics/ByRefLike/Validate.cs | 1 - .../generics/ByRefLike/Validate.csproj | 1 - 8 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/mono/mono/metadata/class-init.c b/src/mono/mono/metadata/class-init.c index 8e064696fe762..ffefe2faa77a7 100644 --- a/src/mono/mono/metadata/class-init.c +++ b/src/mono/mono/metadata/class-init.c @@ -2953,7 +2953,7 @@ mono_class_init_internal (MonoClass *klass) if (klass->inited || mono_class_has_failure (klass)) return !mono_class_has_failure (klass); - /*g_print ("Init class %s\n", mono_type_get_full_name (klass));*/ + // g_print ("Init class %s\n", mono_type_get_full_name (klass)); /* * This function can recursively call itself. diff --git a/src/mono/mono/metadata/class.c b/src/mono/mono/metadata/class.c index c5fcd2a8d7a18..2344a047a0994 100644 --- a/src/mono/mono/metadata/class.c +++ b/src/mono/mono/metadata/class.c @@ -642,8 +642,6 @@ mono_type_is_valid_generic_argument (MonoType *type) case MONO_TYPE_VOID: case MONO_TYPE_TYPEDBYREF: return FALSE; - case MONO_TYPE_VALUETYPE: - return !m_class_is_byreflike (type->data.klass); default: return TRUE; } diff --git a/src/mono/mono/metadata/object-internals.h b/src/mono/mono/metadata/object-internals.h index 257d06a915da9..63d19dae12bfc 100644 --- a/src/mono/mono/metadata/object-internals.h +++ b/src/mono/mono/metadata/object-internals.h @@ -1439,16 +1439,17 @@ typedef struct { /* Keep in sync with System.GenericParameterAttributes */ typedef enum { - GENERIC_PARAMETER_ATTRIBUTE_NON_VARIANT = 0, - GENERIC_PARAMETER_ATTRIBUTE_COVARIANT = 1, - GENERIC_PARAMETER_ATTRIBUTE_CONTRAVARIANT = 2, - GENERIC_PARAMETER_ATTRIBUTE_VARIANCE_MASK = 3, - - GENERIC_PARAMETER_ATTRIBUTE_NO_SPECIAL_CONSTRAINT = 0, - GENERIC_PARAMETER_ATTRIBUTE_REFERENCE_TYPE_CONSTRAINT = 4, - GENERIC_PARAMETER_ATTRIBUTE_VALUE_TYPE_CONSTRAINT = 8, - GENERIC_PARAMETER_ATTRIBUTE_CONSTRUCTOR_CONSTRAINT = 16, - GENERIC_PARAMETER_ATTRIBUTE_SPECIAL_CONSTRAINTS_MASK = 28 + GENERIC_PARAMETER_ATTRIBUTE_NON_VARIANT = 0x0000, + GENERIC_PARAMETER_ATTRIBUTE_COVARIANT = 0x0001, + GENERIC_PARAMETER_ATTRIBUTE_CONTRAVARIANT = 0x0002, + GENERIC_PARAMETER_ATTRIBUTE_VARIANCE_MASK = 0x0003, + + GENERIC_PARAMETER_ATTRIBUTE_NO_SPECIAL_CONSTRAINT = 0x0000, + GENERIC_PARAMETER_ATTRIBUTE_REFERENCE_TYPE_CONSTRAINT = 0x0004, + GENERIC_PARAMETER_ATTRIBUTE_VALUE_TYPE_CONSTRAINT = 0x0008, + GENERIC_PARAMETER_ATTRIBUTE_CONSTRUCTOR_CONSTRAINT = 0x0010, + GENERIC_PARAMETER_ATTRIBUTE_SPECIAL_CONSTRAINTS_MASK = 0x003c, + GENERIC_PARAMETER_ATTRIBUTE_ACCEPT_BYREFLIKE_CONSTRAINTS = 0x0020 // type argument can be ByRefLike } GenericParameterAttributes; typedef struct { diff --git a/src/mono/mono/metadata/verify.c b/src/mono/mono/metadata/verify.c index 660f6226eb009..621599fa4eeeb 100644 --- a/src/mono/mono/metadata/verify.c +++ b/src/mono/mono/metadata/verify.c @@ -87,6 +87,9 @@ is_valid_generic_instantiation (MonoGenericContainer *gc, MonoGenericContext *co return FALSE; } + if (m_class_is_byreflike (paramClass) && (param_info->flags & GENERIC_PARAMETER_ATTRIBUTE_ACCEPT_BYREFLIKE_CONSTRAINTS) == 0) + return FALSE; + if (!param_info->constraints && !(param_info->flags & GENERIC_PARAMETER_ATTRIBUTE_SPECIAL_CONSTRAINTS_MASK)) continue; diff --git a/src/tests/Loader/classloader/generics/ByRefLike/GenericTypeSubstitution.cs b/src/tests/Loader/classloader/generics/ByRefLike/GenericTypeSubstitution.cs index 3453b2a1d3e5e..0c9bf347b9c06 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/GenericTypeSubstitution.cs +++ b/src/tests/Loader/classloader/generics/ByRefLike/GenericTypeSubstitution.cs @@ -12,7 +12,6 @@ public class GenericTypeSubstitution { [Fact] - [SkipOnMono("Mono does not support ByRefLike generics yet")] public static void AllowByRefLike_Substituted_For_AllowByRefLike() { Console.WriteLine($"{nameof(AllowByRefLike_Substituted_For_AllowByRefLike)}..."); @@ -23,7 +22,6 @@ public static void AllowByRefLike_Substituted_For_AllowByRefLike() } [Fact] - [SkipOnMono("Mono does not support ByRefLike generics yet")] public static void NonByRefLike_Substituted_For_AllowByRefLike() { Console.WriteLine($" -- Instantiate: {Exec.TypeSubstitutionInterfaceImplementationNonByRefLike()}"); diff --git a/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.ilproj b/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.ilproj index 58dc9527f8046..8e167b20da08e 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.ilproj +++ b/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.ilproj @@ -2,7 +2,6 @@ library true - true diff --git a/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs b/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs index 4d70945b4c746..1056af934464b 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs +++ b/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs @@ -12,7 +12,6 @@ public class Validate { [Fact] - [SkipOnMono("Mono does not support ByRefLike generics yet")] public static void Validate_TypeLoad() { Console.WriteLine($"{nameof(Validate_TypeLoad)}..."); diff --git a/src/tests/Loader/classloader/generics/ByRefLike/Validate.csproj b/src/tests/Loader/classloader/generics/ByRefLike/Validate.csproj index 8bb4ee77df067..83580f549743d 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/Validate.csproj +++ b/src/tests/Loader/classloader/generics/ByRefLike/Validate.csproj @@ -2,7 +2,6 @@ true - true From 9bc7fff23134f5a1918b5428659b413c0b1454dd Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Wed, 28 Feb 2024 16:06:14 -0500 Subject: [PATCH 02/16] Try to fix format --- src/mono/mono/metadata/object-internals.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mono/mono/metadata/object-internals.h b/src/mono/mono/metadata/object-internals.h index 63d19dae12bfc..2c0097a3e9dd0 100644 --- a/src/mono/mono/metadata/object-internals.h +++ b/src/mono/mono/metadata/object-internals.h @@ -1444,11 +1444,11 @@ typedef enum { GENERIC_PARAMETER_ATTRIBUTE_CONTRAVARIANT = 0x0002, GENERIC_PARAMETER_ATTRIBUTE_VARIANCE_MASK = 0x0003, - GENERIC_PARAMETER_ATTRIBUTE_NO_SPECIAL_CONSTRAINT = 0x0000, - GENERIC_PARAMETER_ATTRIBUTE_REFERENCE_TYPE_CONSTRAINT = 0x0004, - GENERIC_PARAMETER_ATTRIBUTE_VALUE_TYPE_CONSTRAINT = 0x0008, - GENERIC_PARAMETER_ATTRIBUTE_CONSTRUCTOR_CONSTRAINT = 0x0010, - GENERIC_PARAMETER_ATTRIBUTE_SPECIAL_CONSTRAINTS_MASK = 0x003c, + GENERIC_PARAMETER_ATTRIBUTE_NO_SPECIAL_CONSTRAINT = 0x0000, + GENERIC_PARAMETER_ATTRIBUTE_REFERENCE_TYPE_CONSTRAINT = 0x0004, + GENERIC_PARAMETER_ATTRIBUTE_VALUE_TYPE_CONSTRAINT = 0x0008, + GENERIC_PARAMETER_ATTRIBUTE_CONSTRUCTOR_CONSTRAINT = 0x0010, + GENERIC_PARAMETER_ATTRIBUTE_SPECIAL_CONSTRAINTS_MASK = 0x003c, GENERIC_PARAMETER_ATTRIBUTE_ACCEPT_BYREFLIKE_CONSTRAINTS = 0x0020 // type argument can be ByRefLike } GenericParameterAttributes; From fa44429f34e777b15124645f24a1714743328051 Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Thu, 29 Feb 2024 10:47:46 -0500 Subject: [PATCH 03/16] Address review feedback and enable more tests --- src/mono/mono/metadata/class.c | 1 - src/tests/Loader/classloader/generics/ByRefLike/Validate.cs | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/mono/mono/metadata/class.c b/src/mono/mono/metadata/class.c index 2344a047a0994..244567efeaf17 100644 --- a/src/mono/mono/metadata/class.c +++ b/src/mono/mono/metadata/class.c @@ -640,7 +640,6 @@ mono_type_is_valid_generic_argument (MonoType *type) { switch (type->type) { case MONO_TYPE_VOID: - case MONO_TYPE_TYPEDBYREF: return FALSE; default: return TRUE; diff --git a/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs b/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs index 1056af934464b..0b9f9f731990a 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs +++ b/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs @@ -28,7 +28,6 @@ public static void Validate_TypeLoad() } [Fact] - [SkipOnMono("Mono does not support ByRefLike generics yet")] public static void Validate_Casting_Scenarios() { Console.WriteLine($"{nameof(Validate_Casting_Scenarios)}..."); @@ -72,7 +71,6 @@ public static void Validate_InvalidOpCode_Scenarios() } [Fact] - [SkipOnMono("Mono does not support ByRefLike generics yet")] public static void Validate_Inlining_Behavior() { Console.WriteLine($"{nameof(Validate_Inlining_Behavior)}..."); From e340bc7fd46a03324c37fab7f7f5f33640eed124 Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Thu, 29 Feb 2024 10:51:18 -0500 Subject: [PATCH 04/16] Fix format --- src/mono/mono/metadata/object-internals.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mono/mono/metadata/object-internals.h b/src/mono/mono/metadata/object-internals.h index 2c0097a3e9dd0..daaba307f17db 100644 --- a/src/mono/mono/metadata/object-internals.h +++ b/src/mono/mono/metadata/object-internals.h @@ -1444,12 +1444,12 @@ typedef enum { GENERIC_PARAMETER_ATTRIBUTE_CONTRAVARIANT = 0x0002, GENERIC_PARAMETER_ATTRIBUTE_VARIANCE_MASK = 0x0003, - GENERIC_PARAMETER_ATTRIBUTE_NO_SPECIAL_CONSTRAINT = 0x0000, - GENERIC_PARAMETER_ATTRIBUTE_REFERENCE_TYPE_CONSTRAINT = 0x0004, - GENERIC_PARAMETER_ATTRIBUTE_VALUE_TYPE_CONSTRAINT = 0x0008, - GENERIC_PARAMETER_ATTRIBUTE_CONSTRUCTOR_CONSTRAINT = 0x0010, - GENERIC_PARAMETER_ATTRIBUTE_SPECIAL_CONSTRAINTS_MASK = 0x003c, - GENERIC_PARAMETER_ATTRIBUTE_ACCEPT_BYREFLIKE_CONSTRAINTS = 0x0020 // type argument can be ByRefLike + GENERIC_PARAMETER_ATTRIBUTE_NO_SPECIAL_CONSTRAINT = 0x0000, + GENERIC_PARAMETER_ATTRIBUTE_REFERENCE_TYPE_CONSTRAINT = 0x0004, + GENERIC_PARAMETER_ATTRIBUTE_VALUE_TYPE_CONSTRAINT = 0x0008, + GENERIC_PARAMETER_ATTRIBUTE_CONSTRUCTOR_CONSTRAINT = 0x0010, + GENERIC_PARAMETER_ATTRIBUTE_ACCEPT_BYREFLIKE_CONSTRAINTS = 0x0020, // type argument can be ByRefLike + GENERIC_PARAMETER_ATTRIBUTE_SPECIAL_CONSTRAINTS_MASK = 0x003c } GenericParameterAttributes; typedef struct { From 47e2454cf771ae22b7df33400e98b1a5baab439c Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Thu, 29 Feb 2024 16:26:31 -0500 Subject: [PATCH 05/16] Commenting out methods with array of T to workaround AOT failure --- .../generics/ByRefLike/InvalidCSharp.il | 58 +++++++++---------- .../generics/ByRefLike/Validate.cs | 4 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il b/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il index d81452d398af9..058dabe0fa716 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il +++ b/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il @@ -623,35 +623,35 @@ ret } - .method public hidebysig static - void AllocArrayOfT_Invalid() cil managed - { - .locals init ( - [0] valuetype InvalidCSharp.GenericByRefLike_Over`1 - ) - - ldloca.s 0 - initobj valuetype InvalidCSharp.GenericByRefLike_Over`1 - ldloca.s 0 - call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::AllocArrayOfT() - pop - ret - } - - .method public hidebysig static - void AllocMultiDimArrayOfT_Invalid() cil managed - { - .locals init ( - [0] valuetype InvalidCSharp.GenericByRefLike_Over`1 - ) - - ldloca.s 0 - initobj valuetype InvalidCSharp.GenericByRefLike_Over`1 - ldloca.s 0 - call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::AllocMultiDimArrayOfT() - pop - ret - } + // .method public hidebysig static + // void AllocArrayOfT_Invalid() cil managed + // { + // .locals init ( + // [0] valuetype InvalidCSharp.GenericByRefLike_Over`1 + // ) + + // ldloca.s 0 + // initobj valuetype InvalidCSharp.GenericByRefLike_Over`1 + // ldloca.s 0 + // call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::AllocArrayOfT() + // pop + // ret + // } + + // .method public hidebysig static + // void AllocMultiDimArrayOfT_Invalid() cil managed + // { + // .locals init ( + // [0] valuetype InvalidCSharp.GenericByRefLike_Over`1 + // ) + + // ldloca.s 0 + // initobj valuetype InvalidCSharp.GenericByRefLike_Over`1 + // ldloca.s 0 + // call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::AllocMultiDimArrayOfT() + // pop + // ret + // } .method public hidebysig static string GenericClassWithStaticField_Invalid() cil managed diff --git a/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs b/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs index 0b9f9f731990a..a82bcdcdc0245 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs +++ b/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs @@ -62,8 +62,8 @@ public static void Validate_InvalidOpCode_Scenarios() // These methods uses opcodes that are not able to handle ByRefLike type operands. // The TypeLoader prevents these invalid types from being constructed. We rely on // the failure to construct these invalid types to block opcode usage. - Assert.Throws(() => { Exec.AllocArrayOfT_Invalid(); }); - Assert.Throws(() => { Exec.AllocMultiDimArrayOfT_Invalid(); }); + // Assert.Throws(() => { Exec.AllocArrayOfT_Invalid(); }); + // Assert.Throws(() => { Exec.AllocMultiDimArrayOfT_Invalid(); }); Assert.Throws(() => { Exec.GenericClassWithStaticField_Invalid(); }); // Test that explicitly tries to box a ByRefLike type. From e4d441c1f3dd0adf3d5dd9c6e87731cca7e6a774 Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Fri, 1 Mar 2024 10:21:00 -0500 Subject: [PATCH 06/16] Split up the testcases --- .../classloader/generics/ByRefLike/Validate.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs b/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs index a82bcdcdc0245..99561f845d5fa 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs +++ b/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs @@ -42,7 +42,6 @@ public static void Validate_Casting_Scenarios() } [Fact] - [SkipOnMono("Mono does not support ByRefLike generics yet")] public static void Validate_RecognizedOpCodeSequences_Scenarios() { Console.WriteLine($"{nameof(Validate_RecognizedOpCodeSequences_Scenarios)}..."); @@ -62,14 +61,26 @@ public static void Validate_InvalidOpCode_Scenarios() // These methods uses opcodes that are not able to handle ByRefLike type operands. // The TypeLoader prevents these invalid types from being constructed. We rely on // the failure to construct these invalid types to block opcode usage. - // Assert.Throws(() => { Exec.AllocArrayOfT_Invalid(); }); - // Assert.Throws(() => { Exec.AllocMultiDimArrayOfT_Invalid(); }); Assert.Throws(() => { Exec.GenericClassWithStaticField_Invalid(); }); // Test that explicitly tries to box a ByRefLike type. Assert.Throws(() => { Exec.BoxAsObject(); }); } + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/99165")] + public static void Validate_InvalidOpCode_Scenarios_ArrayOfT() + { + Console.WriteLine($"{nameof(Validate_InvalidOpCode_Scenarios_ArrayOfT)}..."); + + // These methods uses opcodes that are not able to handle ByRefLike type operands. + // The TypeLoader prevents these invalid types from being constructed. We rely on + // the failure to construct these invalid types to block opcode usage. + + // Assert.Throws(() => { Exec.AllocArrayOfT_Invalid(); }); + // Assert.Throws(() => { Exec.AllocMultiDimArrayOfT_Invalid(); }); + } + [Fact] public static void Validate_Inlining_Behavior() { From 4d5f4ea0f8c93d5f7662332bf14b468c254aeb1e Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Mon, 4 Mar 2024 15:06:21 -0500 Subject: [PATCH 07/16] Throw type loading exception when trying to create type arrays with ByRefLike types --- src/mono/mono/metadata/loader.c | 1 - src/mono/mono/mini/method-to-ir.c | 2 +- src/mono/mono/mini/mini-generic-sharing.c | 2 + .../generics/ByRefLike/InvalidCSharp.il | 58 +++++++++---------- .../generics/ByRefLike/Validate.cs | 5 +- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/mono/mono/metadata/loader.c b/src/mono/mono/metadata/loader.c index 67c613b9631ae..5f9e5c0e7d1f1 100644 --- a/src/mono/mono/metadata/loader.c +++ b/src/mono/mono/metadata/loader.c @@ -823,7 +823,6 @@ mono_method_search_in_array_class (MonoClass *klass, const char *name, MonoMetho int i; mono_class_setup_methods (klass); - g_assert (!mono_class_has_failure (klass)); /*FIXME this should not fail, right?*/ int mcount = mono_class_get_method_count (klass); MonoMethod **klass_methods = m_class_get_methods (klass); for (i = 0; i < mcount; ++i) { diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index c696cb634566a..494aa4b4cdce5 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -9277,7 +9277,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b mono_save_token_info (cfg, image, token, cmethod); - if (!mono_class_init_internal (cmethod->klass)) + if (mono_class_has_failure (cmethod->klass) || !mono_class_init_internal (cmethod->klass)) TYPE_LOAD_ERROR (cmethod->klass); context_used = mini_method_check_context_used (cfg, cmethod); diff --git a/src/mono/mono/mini/mini-generic-sharing.c b/src/mono/mono/mini/mini-generic-sharing.c index 58440dcdc3599..c5c4e8b44e0ba 100644 --- a/src/mono/mono/mini/mini-generic-sharing.c +++ b/src/mono/mono/mini/mini-generic-sharing.c @@ -590,6 +590,7 @@ inflate_info (MonoMemoryManager *mem_manager, MonoRuntimeGenericContextInfoTempl inflated_method = mono_class_inflate_generic_method_checked (method, context, error); g_assert (is_ok (error)); /* FIXME don't swallow the error */ } + g_assert (inflated_method); mono_class_init_internal (inflated_method->klass); g_assert (inflated_method->klass == inflated_class); return inflated_method; @@ -654,6 +655,7 @@ inflate_info (MonoMemoryManager *mem_manager, MonoRuntimeGenericContextInfoTempl inflated_method = mono_class_inflate_generic_method_checked (method, context, error); g_assert (is_ok (error)); /* FIXME don't swallow the error */ } + g_assert (inflated_method); mono_class_init_internal (inflated_method->klass); g_assert (inflated_method->klass == inflated_class); diff --git a/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il b/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il index 058dabe0fa716..d81452d398af9 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il +++ b/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il @@ -623,35 +623,35 @@ ret } - // .method public hidebysig static - // void AllocArrayOfT_Invalid() cil managed - // { - // .locals init ( - // [0] valuetype InvalidCSharp.GenericByRefLike_Over`1 - // ) - - // ldloca.s 0 - // initobj valuetype InvalidCSharp.GenericByRefLike_Over`1 - // ldloca.s 0 - // call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::AllocArrayOfT() - // pop - // ret - // } - - // .method public hidebysig static - // void AllocMultiDimArrayOfT_Invalid() cil managed - // { - // .locals init ( - // [0] valuetype InvalidCSharp.GenericByRefLike_Over`1 - // ) - - // ldloca.s 0 - // initobj valuetype InvalidCSharp.GenericByRefLike_Over`1 - // ldloca.s 0 - // call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::AllocMultiDimArrayOfT() - // pop - // ret - // } + .method public hidebysig static + void AllocArrayOfT_Invalid() cil managed + { + .locals init ( + [0] valuetype InvalidCSharp.GenericByRefLike_Over`1 + ) + + ldloca.s 0 + initobj valuetype InvalidCSharp.GenericByRefLike_Over`1 + ldloca.s 0 + call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::AllocArrayOfT() + pop + ret + } + + .method public hidebysig static + void AllocMultiDimArrayOfT_Invalid() cil managed + { + .locals init ( + [0] valuetype InvalidCSharp.GenericByRefLike_Over`1 + ) + + ldloca.s 0 + initobj valuetype InvalidCSharp.GenericByRefLike_Over`1 + ldloca.s 0 + call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::AllocMultiDimArrayOfT() + pop + ret + } .method public hidebysig static string GenericClassWithStaticField_Invalid() cil managed diff --git a/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs b/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs index 99561f845d5fa..b43d21630d476 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs +++ b/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs @@ -68,7 +68,6 @@ public static void Validate_InvalidOpCode_Scenarios() } [Fact] - [SkipOnMono("https://github.com/dotnet/runtime/issues/99165")] public static void Validate_InvalidOpCode_Scenarios_ArrayOfT() { Console.WriteLine($"{nameof(Validate_InvalidOpCode_Scenarios_ArrayOfT)}..."); @@ -77,8 +76,8 @@ public static void Validate_InvalidOpCode_Scenarios_ArrayOfT() // The TypeLoader prevents these invalid types from being constructed. We rely on // the failure to construct these invalid types to block opcode usage. - // Assert.Throws(() => { Exec.AllocArrayOfT_Invalid(); }); - // Assert.Throws(() => { Exec.AllocMultiDimArrayOfT_Invalid(); }); + Assert.Throws(() => { Exec.AllocArrayOfT_Invalid(); }); + Assert.Throws(() => { Exec.AllocMultiDimArrayOfT_Invalid(); }); } [Fact] From 265399625e22a305b7a53863e6c79e79322ac745 Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Tue, 5 Mar 2024 14:20:26 -0500 Subject: [PATCH 08/16] Fix box and stsfld/ldsfld/ldsflda --- src/mono/mono/mini/method-to-ir.c | 23 +++++++++++-------- src/mono/mono/mini/mini-generic-sharing.c | 2 ++ .../generics/ByRefLike/Validate.cs | 16 ++----------- 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 494aa4b4cdce5..31a399affbeec 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -2320,16 +2320,13 @@ emit_type_load_failure (MonoCompile* cfg, MonoClass* klass) } static void -emit_invalid_program_with_msg (MonoCompile *cfg, MonoError *error_msg, MonoMethod *caller, MonoMethod *callee) +emit_invalid_program_with_msg (MonoCompile *cfg, char *error_msg) { - g_assert (!is_ok (error_msg)); - - char *str = mono_mem_manager_strdup (cfg->mem_manager, mono_error_get_message (error_msg)); MonoInst *iargs[1]; if (cfg->compile_aot) - EMIT_NEW_LDSTRLITCONST (cfg, iargs [0], str); + EMIT_NEW_LDSTRLITCONST (cfg, iargs [0], error_msg); else - EMIT_NEW_PCONST (cfg, iargs [0], str); + EMIT_NEW_PCONST (cfg, iargs [0], error_msg); mono_emit_jit_icall (cfg, mono_throw_invalid_program, iargs); } @@ -3416,8 +3413,8 @@ mini_emit_box (MonoCompile *cfg, MonoInst *val, MonoClass *klass, int context_us MonoInst *alloc, *ins; if (G_UNLIKELY (m_class_is_byreflike (klass))) { - mono_error_set_bad_image (cfg->error, m_class_get_image (cfg->method->klass), "Cannot box IsByRefLike type '%s.%s'", m_class_get_name_space (klass), m_class_get_name (klass)); - mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR); + mono_error_set_invalid_program (cfg->error, "Cannot box IsByRefLike type '%s.%s'", m_class_get_name_space (klass), m_class_get_name (klass)); + mono_cfg_set_exception (cfg, MONO_EXCEPTION_INVALID_PROGRAM); return NULL; } @@ -9990,8 +9987,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b case MONO_CEE_STSFLD: { MonoClassField *field; guint foffset; - gboolean is_instance; gpointer addr = NULL; + gboolean is_instance; + gboolean is_static; gboolean is_special_static; MonoType *ftype; MonoInst *store_val = NULL; @@ -10076,6 +10074,10 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b is_instance = FALSE; } + is_static = (il_op == MONO_CEE_LDSFLD || il_op == MONO_CEE_LDSFLDA || il_op == MONO_CEE_STSFLD); + if (is_static && G_UNLIKELY (m_class_is_byreflike (klass))) + TYPE_LOAD_ERROR (klass); + context_used = mini_class_check_context_used (cfg, klass); if (il_op == MONO_CEE_LDSFLD) { @@ -11840,7 +11842,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b /* if we couldn't create a wrapper because cmethod isn't supposed to have an UnmanagedCallersOnly attribute, follow CoreCLR behavior and throw when the method with the ldftn is executing, not when it is being compiled. */ - emit_invalid_program_with_msg (cfg, wrapper_error, method, cmethod); + char *err_msg = mono_mem_manager_strdup (cfg->mem_manager, mono_error_get_message (wrapper_error)); + emit_invalid_program_with_msg (cfg, err_msg); mono_error_cleanup (wrapper_error); EMIT_NEW_PCONST (cfg, ins, NULL); *sp++ = ins; diff --git a/src/mono/mono/mini/mini-generic-sharing.c b/src/mono/mono/mini/mini-generic-sharing.c index c5c4e8b44e0ba..cd482c75e367a 100644 --- a/src/mono/mono/mini/mini-generic-sharing.c +++ b/src/mono/mono/mini/mini-generic-sharing.c @@ -584,6 +584,7 @@ inflate_info (MonoMemoryManager *mem_manager, MonoRuntimeGenericContextInfoTempl if (m_class_get_byval_arg (inflated_class)->type == MONO_TYPE_ARRAY || m_class_get_byval_arg (inflated_class)->type == MONO_TYPE_SZARRAY) { + g_assert (!mono_class_has_failure (inflated_class)); inflated_method = mono_method_search_in_array_class (inflated_class, method->name, method->signature); } else { @@ -649,6 +650,7 @@ inflate_info (MonoMemoryManager *mem_manager, MonoRuntimeGenericContextInfoTempl if (m_class_get_byval_arg (inflated_class)->type == MONO_TYPE_ARRAY || m_class_get_byval_arg (inflated_class)->type == MONO_TYPE_SZARRAY) { + g_assert (!mono_class_has_failure (inflated_class)); inflated_method = mono_method_search_in_array_class (inflated_class, method->name, method->signature); } else { diff --git a/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs b/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs index b43d21630d476..4a50fe7c81cda 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs +++ b/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs @@ -53,7 +53,6 @@ public static void Validate_RecognizedOpCodeSequences_Scenarios() } [Fact] - [SkipOnMono("Mono does not support ByRefLike generics yet")] public static void Validate_InvalidOpCode_Scenarios() { Console.WriteLine($"{nameof(Validate_InvalidOpCode_Scenarios)}..."); @@ -61,25 +60,14 @@ public static void Validate_InvalidOpCode_Scenarios() // These methods uses opcodes that are not able to handle ByRefLike type operands. // The TypeLoader prevents these invalid types from being constructed. We rely on // the failure to construct these invalid types to block opcode usage. + Assert.Throws(() => { Exec.AllocArrayOfT_Invalid(); }); + Assert.Throws(() => { Exec.AllocMultiDimArrayOfT_Invalid(); }); Assert.Throws(() => { Exec.GenericClassWithStaticField_Invalid(); }); // Test that explicitly tries to box a ByRefLike type. Assert.Throws(() => { Exec.BoxAsObject(); }); } - [Fact] - public static void Validate_InvalidOpCode_Scenarios_ArrayOfT() - { - Console.WriteLine($"{nameof(Validate_InvalidOpCode_Scenarios_ArrayOfT)}..."); - - // These methods uses opcodes that are not able to handle ByRefLike type operands. - // The TypeLoader prevents these invalid types from being constructed. We rely on - // the failure to construct these invalid types to block opcode usage. - - Assert.Throws(() => { Exec.AllocArrayOfT_Invalid(); }); - Assert.Throws(() => { Exec.AllocMultiDimArrayOfT_Invalid(); }); - } - [Fact] public static void Validate_Inlining_Behavior() { From 9f1b2407cf6d80ee0d02a14dde5dd5cbb11c9d82 Mon Sep 17 00:00:00 2001 From: Fan Yang Date: Wed, 6 Mar 2024 15:10:40 -0500 Subject: [PATCH 09/16] Disable a test cause it is failing with interpreter --- src/tests/Loader/classloader/generics/ByRefLike/Validate.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs b/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs index 4a50fe7c81cda..3ad82bc733279 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs +++ b/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs @@ -42,6 +42,7 @@ public static void Validate_Casting_Scenarios() } [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/99379")] public static void Validate_RecognizedOpCodeSequences_Scenarios() { Console.WriteLine($"{nameof(Validate_RecognizedOpCodeSequences_Scenarios)}..."); From 96e2b56c5d770220035084c4c0adcbd6561e09de Mon Sep 17 00:00:00 2001 From: fanyang-mono Date: Thu, 7 Mar 2024 14:31:11 -0500 Subject: [PATCH 10/16] For load/store static field, only error out when it is a generic class with byreflike type parameter --- src/mono/mono/mini/method-to-ir.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 31a399affbeec..2c00cfc8d8455 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -10075,8 +10075,14 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b } is_static = (il_op == MONO_CEE_LDSFLD || il_op == MONO_CEE_LDSFLDA || il_op == MONO_CEE_STSFLD); - if (is_static && G_UNLIKELY (m_class_is_byreflike (klass))) - TYPE_LOAD_ERROR (klass); + if (is_static && mono_class_is_ginst (klass)) { + MonoGenericContext *context = &mono_class_get_generic_class (klass)->context; + if (context->class_inst) { + for (guint i = 0; i < context->class_inst->type_argc; ++i) + if (m_class_is_byreflike (mono_class_from_mono_type_internal (context->class_inst->type_argv [i]))) + TYPE_LOAD_ERROR (klass); + } + } context_used = mini_class_check_context_used (cfg, klass); From 063eccccb52a565b2a3fff12a6817a5e703f3c71 Mon Sep 17 00:00:00 2001 From: fanyang-mono Date: Thu, 7 Mar 2024 16:45:09 -0500 Subject: [PATCH 11/16] Fix interpreter box byreflike exception ID --- src/mono/mono/mini/interp/transform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index ac654631313fe..6a20f5c0b3469 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -6896,7 +6896,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, td->ip += 5; } else { if (G_UNLIKELY (m_class_is_byreflike (klass))) { - mono_error_set_bad_image (error, image, "Cannot box IsByRefLike type '%s.%s'", m_class_get_name_space (klass), m_class_get_name (klass)); + mono_error_set_invalid_program (error, "Cannot box IsByRefLike type '%s.%s'", m_class_get_name_space (klass), m_class_get_name (klass)); goto exit; } From da70ed3245e9c77dc1fd09178e52c0d406ebe5d7 Mon Sep 17 00:00:00 2001 From: fanyang-mono Date: Fri, 8 Mar 2024 13:06:20 -0500 Subject: [PATCH 12/16] Relax type check --- src/mono/mono/metadata/metadata.c | 53 +------------------------------ 1 file changed, 1 insertion(+), 52 deletions(-) diff --git a/src/mono/mono/metadata/metadata.c b/src/mono/mono/metadata/metadata.c index f716029223298..2c29c393faa80 100644 --- a/src/mono/mono/metadata/metadata.c +++ b/src/mono/mono/metadata/metadata.c @@ -3921,56 +3921,6 @@ mono_metadata_get_shared_type (MonoType *type) return NULL; } -static gboolean -compare_type_literals (MonoImage *image, int class_type, int type_type, MonoError *error) -{ - error_init (error); - - /* _byval_arg.type can be zero if we're decoding a type that references a class been loading. - * See mcs/test/gtest-440. and #650936. - * FIXME This better be moved to the metadata verifier as it can catch more cases. - */ - if (!class_type) - return TRUE; - /* NET 1.1 assemblies might encode string and object in a denormalized way. - * See #675464. - */ - if (class_type == type_type) - return TRUE; - - if (type_type == MONO_TYPE_CLASS) { - if (class_type == MONO_TYPE_STRING || class_type == MONO_TYPE_OBJECT) - return TRUE; - //XXX stringify this argument - mono_error_set_bad_image (error, image, "Expected reference type but got type kind %d", class_type); - return FALSE; - } - - g_assert (type_type == MONO_TYPE_VALUETYPE); - switch (class_type) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_CHAR: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I8: - case MONO_TYPE_U8: - case MONO_TYPE_R4: - case MONO_TYPE_R8: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_CLASS: - return TRUE; - default: - //XXX stringify this argument - mono_error_set_bad_image (error, image, "Expected value type but got type kind %d", class_type); - return FALSE; - } -} - static gboolean verify_var_type_and_container (MonoImage *image, int var_type, MonoGenericContainer *container, MonoError *error) { @@ -4049,8 +3999,7 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer if (!klass) return FALSE; - if (!compare_type_literals (m, m_class_get_byval_arg (klass)->type, type->type, error)) - return FALSE; + type->type = m_class_get_byval_arg (klass)->type; // if we expected a valuetype but got a class, or vice versa, that's ok. .NET Core doesn't care for the distinction anymore break; } From 390aa32bf0639a022d265d991a3663585a4a0d54 Mon Sep 17 00:00:00 2001 From: fanyang-mono Date: Fri, 8 Mar 2024 13:13:49 -0500 Subject: [PATCH 13/16] Enable more tests --- .../classloader/generics/ByRefLike/GenericTypeSubstitution.cs | 1 - src/tests/Loader/classloader/generics/ByRefLike/Validate.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/tests/Loader/classloader/generics/ByRefLike/GenericTypeSubstitution.cs b/src/tests/Loader/classloader/generics/ByRefLike/GenericTypeSubstitution.cs index c8c5c705f3a8e..75b22b974792c 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/GenericTypeSubstitution.cs +++ b/src/tests/Loader/classloader/generics/ByRefLike/GenericTypeSubstitution.cs @@ -32,7 +32,6 @@ public static void NonByRefLike_Substituted_For_AllowByRefLike() } [Fact] - [SkipOnMono("Mono does not support ByRefLike generics yet")] public static void AllowByRefLike_Substituted_For_NonByRefLike() { Console.WriteLine($"{nameof(AllowByRefLike_Substituted_For_NonByRefLike)}..."); diff --git a/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs b/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs index 727cd6aae70e7..4d7c05d6db962 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs +++ b/src/tests/Loader/classloader/generics/ByRefLike/Validate.cs @@ -84,7 +84,6 @@ public static void Validate_Inlining_Behavior() } // [Fact] - [SkipOnMono("Mono does not support ByRefLike generics yet")] public static void Validate_MemberDiscoveryViaReflection_ForSpanReadOnlySpan() { Console.WriteLine($"{nameof(Validate_MemberDiscoveryViaReflection_ForSpanReadOnlySpan)}..."); From 308697437603907931736928c6e40461002f4a9c Mon Sep 17 00:00:00 2001 From: fanyang-mono Date: Fri, 8 Mar 2024 14:30:47 -0500 Subject: [PATCH 14/16] Revert the change for relaxing type check --- src/mono/mono/metadata/metadata.c | 53 ++++++++++++++++++- .../generics/ByRefLike/InvalidCSharp.il | 2 +- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/metadata/metadata.c b/src/mono/mono/metadata/metadata.c index 2c29c393faa80..b432e7f07dc54 100644 --- a/src/mono/mono/metadata/metadata.c +++ b/src/mono/mono/metadata/metadata.c @@ -3921,6 +3921,56 @@ mono_metadata_get_shared_type (MonoType *type) return NULL; } +static gboolean +compare_type_literals (MonoImage *image, int class_type, int type_type, MonoError *error) +{ + error_init (error); + + /* _byval_arg.type can be zero if we're decoding a type that references a class been loading. + * See mcs/test/gtest-440. and #650936. + * FIXME This better be moved to the metadata verifier as it can catch more cases. + */ + if (!class_type) + return TRUE; + /* NET 1.1 assemblies might encode string and object in a denormalized way. + * See #675464. + */ + if (class_type == type_type) + return TRUE; + + if (type_type == MONO_TYPE_CLASS) { + if (class_type == MONO_TYPE_STRING || class_type == MONO_TYPE_OBJECT) + return TRUE; + //XXX stringify this argument + mono_error_set_type_load_name (error, NULL, NULL, "Expected reference type but got type kind %d", class_type); + return FALSE; + } + + g_assert (type_type == MONO_TYPE_VALUETYPE); + switch (class_type) { + case MONO_TYPE_BOOLEAN: + case MONO_TYPE_CHAR: + case MONO_TYPE_I1: + case MONO_TYPE_U1: + case MONO_TYPE_I2: + case MONO_TYPE_U2: + case MONO_TYPE_I4: + case MONO_TYPE_U4: + case MONO_TYPE_I8: + case MONO_TYPE_U8: + case MONO_TYPE_R4: + case MONO_TYPE_R8: + case MONO_TYPE_I: + case MONO_TYPE_U: + case MONO_TYPE_CLASS: + return TRUE; + default: + //XXX stringify this argument + mono_error_set_type_load_name (error, NULL, NULL, "Expected value type but got type kind %d", class_type); + return FALSE; + } +} + static gboolean verify_var_type_and_container (MonoImage *image, int var_type, MonoGenericContainer *container, MonoError *error) { @@ -3999,7 +4049,8 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer if (!klass) return FALSE; - type->type = m_class_get_byval_arg (klass)->type; // if we expected a valuetype but got a class, or vice versa, that's ok. .NET Core doesn't care for the distinction anymore + if (!compare_type_literals (m, m_class_get_byval_arg (klass)->type, type->type, error)) + return FALSE; break; } diff --git a/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il b/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il index de2b842fed9e8..3ab2730bcb890 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il +++ b/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il @@ -551,7 +551,7 @@ .method public hidebysig static class [System.Runtime]System.Type GenericByRefLike_ConstraintsAreIndependent_Interface_ByRefLike_Invalid() cil managed { - newobj instance void class InvalidCSharp.GenericClass_IndependentConstraints`2::.ctor() + newobj instance void class InvalidCSharp.GenericClass_IndependentConstraints`2::.ctor() callvirt instance class [System.Runtime]System.Type [System.Runtime]System.Object::GetType() ret } From bdcb7580b561e1ab016f2ecfb473aad2df98f4cb Mon Sep 17 00:00:00 2001 From: fanyang-mono Date: Tue, 12 Mar 2024 15:21:11 -0400 Subject: [PATCH 15/16] Remove unreached check --- src/mono/mono/mini/method-to-ir.c | 9 --------- .../classloader/generics/ByRefLike/InvalidCSharp.il | 1 + 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 976178be330ee..075b0bed88c2c 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -10079,15 +10079,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b is_instance = FALSE; } - is_static = (il_op == MONO_CEE_LDSFLD || il_op == MONO_CEE_LDSFLDA || il_op == MONO_CEE_STSFLD); - if (is_static && mono_class_is_ginst (klass)) { - MonoGenericContext *context = &mono_class_get_generic_class (klass)->context; - if (context->class_inst) { - for (guint i = 0; i < context->class_inst->type_argc; ++i) - if (m_class_is_byreflike (mono_class_from_mono_type_internal (context->class_inst->type_argv [i]))) - TYPE_LOAD_ERROR (klass); - } - } context_used = mini_class_check_context_used (cfg, klass); diff --git a/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il b/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il index 3ab2730bcb890..72f0dc67f69e8 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il +++ b/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il @@ -344,6 +344,7 @@ ret } + .field public static class InvalidCSharp.GenericClass_Over`1 StaticField1 .field public static !T StaticField } From 636d8564727a6fbf85c7e4da8fef749b22897304 Mon Sep 17 00:00:00 2001 From: fanyang-mono Date: Tue, 12 Mar 2024 16:00:57 -0400 Subject: [PATCH 16/16] remove unused variable --- src/mono/mono/mini/method-to-ir.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 075b0bed88c2c..0a0443b15506d 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -9994,7 +9994,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b guint foffset; gpointer addr = NULL; gboolean is_instance; - gboolean is_static; gboolean is_special_static; MonoType *ftype; MonoInst *store_val = NULL;