diff options
author | Ludovic Henry <luhenry@microsoft.com> | 2018-04-24 20:46:20 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-24 20:46:20 +0300 |
commit | ea8a24b1bbf950699336bd56e9bab9f046da11c5 (patch) | |
tree | 90558940ecf4cb690dec749589c0b81b72a578b2 | |
parent | a5b924fa68ab4291fe021a460e7beb657c30641e (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.il | 23 | ||||
-rw-r--r-- | mono/mini/method-to-ir.c | 4 |
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 */ |