Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Henry <luhenry@microsoft.com>2018-04-24 20:46:20 +0300
committerGitHub <noreply@github.com>2018-04-24 20:46:20 +0300
commitea8a24b1bbf950699336bd56e9bab9f046da11c5 (patch)
tree90558940ecf4cb690dec749589c0b81b72a578b2
parenta5b924fa68ab4291fe021a460e7beb657c30641e (diff)
[2017-12] [mini] Don't verify types if you store to a pointer byref. (#8425)mono-5.10.1.57
* [mini] Don't verify types if you store to a pointer byref. Workarounds #8403. * [mini] Add regression test for punting a type system check.
-rw-r--r--mono/mini/iltests.il23
-rw-r--r--mono/mini/method-to-ir.c4
2 files changed, 25 insertions, 2 deletions
diff --git a/mono/mini/iltests.il b/mono/mini/iltests.il
index 3c512358729..1bcf07af6bd 100644
--- a/mono/mini/iltests.il
+++ b/mono/mini/iltests.il
@@ -3177,4 +3177,27 @@ L_3:
ldc.i4.0
ret
}
+
+ .method public hidebysig static int32 test_1_dont_verify_ptr_byrefs () cil managed
+ {
+ .locals init (int32 v_0, int32 *& v_2, int32 *v_1)
+
+ //v_0 = 1
+ ldc.i4.1
+ stloc.0
+
+ //v_1 = &v_0 < bad store of `int32&` to ìnt32*&` but must work
+ ldloca v_0
+ stloc.1
+
+ //v_2 = (intptr)v_1
+ ldloc.1
+ conv.u
+ stloc.2
+
+ //return *v_2
+ ldloc.2
+ ldind.i4
+ ret
+ }
}
diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c
index 364b81e690f..f6eccc4224b 100644
--- a/mono/mini/method-to-ir.c
+++ b/mono/mini/method-to-ir.c
@@ -1850,8 +1850,8 @@ target_type_is_incompatible (MonoCompile *cfg, MonoType *target, MonoInst *arg)
MonoClass *target_class_lowered = mono_class_from_mono_type (mini_get_underlying_type (&mono_class_from_mono_type (target)->byval_arg));
MonoClass *source_class_lowered = mono_class_from_mono_type (mini_get_underlying_type (&arg->klass->byval_arg));
- /* if the target is native int& or same type */
- if (target->type == MONO_TYPE_I || target_class_lowered == source_class_lowered)
+ /* if the target is native int& or X* or same type */
+ if (target->type == MONO_TYPE_I || target->type == MONO_TYPE_PTR || target_class_lowered == source_class_lowered)
return 0;
/* Both are primitive type byrefs and the source points to a larger type that the destination */