From 71f2f51af9ff1830f6b9ac29f13b238089a4a221 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Tue, 23 Apr 2024 16:29:24 -0700 Subject: [PATCH 1/3] Add test for boxing byreflike fail. --- .../generics/ByRefLike/InvalidCSharp.il | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il b/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il index 2f3f65d1a19952..322e7bf4f708c3 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il +++ b/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il @@ -149,6 +149,41 @@ ret } + .method public hidebysig + instance bool BoxBranchToOther(!T) cil managed + { + ldarg.1 + // Begin sequence + box !!U + brfalse.s NEXT_1 + // End sequence + NEXT_1: + + ldarg.1 + // Begin sequence + box !!U + brfalse NEXT_2 + // End sequence + NEXT_2: + + ldarg.1 + // Begin sequence + box !!U + brtrue.s NEXT_3 + // End sequence + NEXT_3: + + ldarg.1 + // Begin sequence + box !!U + brtrue NEXT_4 + // End sequence + NEXT_4: + + ldc.i4.1 + ret + } + .method public hidebysig instance bool BoxBranch_WithSideEffects(!T&) cil managed { @@ -388,6 +423,14 @@ ) } +.class public sequential ansi sealed beforefieldinit ByRefLikeType2 + extends [System.Runtime]System.ValueType +{ + .custom instance void [System.Runtime]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( + 01 00 00 00 + ) +} + .class interface public auto ansi abstract InvalidCSharp.EmptyInterface { } @@ -651,6 +694,18 @@ call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::BoxBranch(!0) pop + ldloca.s 0 + ldloc 0 + ldfld !0 valuetype InvalidCSharp.GenericByRefLike_Over`1::Field + call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::BoxBranchToOther(!0) + pop + + ldloca.s 0 + ldloc 0 + ldfld !0 valuetype InvalidCSharp.GenericByRefLike_Over`1::Field + call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::BoxBranchToOther(!0) + pop + ldloca.s 0 ldloca.s 0 ldflda !0 valuetype InvalidCSharp.GenericByRefLike_Over`1::Field From f90be4b571c9e7fe01700d633a863045238b158c Mon Sep 17 00:00:00 2001 From: fanyang-mono Date: Wed, 24 Apr 2024 14:08:12 -0400 Subject: [PATCH 2/3] Check if type is compatible right before emitting box --- src/mono/mono/mini/method-to-ir.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 8d569eae92a35d..c8a4fade7d30fa 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -9595,8 +9595,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b if (klass == mono_defaults.void_class) UNVERIFIED; - if (target_type_is_incompatible (cfg, m_class_get_byval_arg (klass), val)) - UNVERIFIED; + /* frequent check in generic code: box (struct), brtrue */ /* @@ -9955,6 +9954,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b MONO_ADD_INS (cfg->cbb, ins); *sp++ = ins; } else { + if (target_type_is_incompatible (cfg, m_class_get_byval_arg (klass), val)) + UNVERIFIED; *sp++ = mini_emit_box (cfg, val, klass, context_used); } CHECK_CFG_EXCEPTION; From 0c81c938cc9fbba997896ee697dc947973b3a97f Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Wed, 24 Apr 2024 13:50:16 -0700 Subject: [PATCH 3/3] Add test for using byreflike type in isinst expressions. --- .../generics/ByRefLike/InvalidCSharp.il | 48 +++++++++++++++---- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il b/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il index 322e7bf4f708c3..8480a5cf452079 100644 --- a/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il +++ b/src/tests/Loader/classloader/generics/ByRefLike/InvalidCSharp.il @@ -319,6 +319,26 @@ ret } + .method public hidebysig + instance bool BoxIsinstBranch_UsingTypeConstraints(class InvalidCSharp.EmptyInterface) cil managed + { + .locals init ( + [0] !!U + ) + ldarg.1 + isinst !!U + brfalse.s NOT_U + ldarg.1 + isinst !!U + unbox.any !!U + stloc.0 + ldc.i4.0 + ret + NOT_U: + ldc.i4.1 + ret + } + .method public hidebysig instance bool AllocArrayOfT() cil managed aggressiveinlining { @@ -423,14 +443,6 @@ ) } -.class public sequential ansi sealed beforefieldinit ByRefLikeType2 - extends [System.Runtime]System.ValueType -{ - .custom instance void [System.Runtime]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( - 01 00 00 00 - ) -} - .class interface public auto ansi abstract InvalidCSharp.EmptyInterface { } @@ -449,6 +461,19 @@ { } +.class public auto ansi beforefieldinit InvalidCSharp.ClassWithInterface + extends [System.Runtime]System.Object + implements InvalidCSharp.EmptyInterface +{ + .method public hidebysig specialname rtspecialname + instance void .ctor () cil managed + { + ldarg.0 + call instance void [System.Runtime]System.Object::.ctor() + ret + } +} + // Generic substitution of allow-byreflike with allow-byreflike .class interface public auto ansi abstract InvalidCSharp.GenericDerivedInterface_OverByRef`1 implements class InvalidCSharp.GenericInterface_Over`1 @@ -697,7 +722,7 @@ ldloca.s 0 ldloc 0 ldfld !0 valuetype InvalidCSharp.GenericByRefLike_Over`1::Field - call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::BoxBranchToOther(!0) + call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::BoxBranchToOther(!0) pop ldloca.s 0 @@ -750,6 +775,11 @@ ldloca.s 0 ldflda !0 valuetype InvalidCSharp.GenericByRefLike_Over`1::Field call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::BoxIsinstBranch_WithSideEffects(!0&) + pop + + ldloca.s 0 + newobj instance void InvalidCSharp.ClassWithInterface::.ctor() + call instance bool valuetype InvalidCSharp.GenericByRefLike_Over`1::BoxIsinstBranch_UsingTypeConstraints(class InvalidCSharp.EmptyInterface) ret }