[interp] fix for ldflda unsafe corner case
authorBernhard Urban <bernhard.urban@xamarin.com>
Tue, 7 Mar 2017 09:47:00 +0000 (10:47 +0100)
committerBernhard Urban <bernhard.urban@xamarin.com>
Wed, 8 Mar 2017 22:02:51 +0000 (23:02 +0100)
mono/mini/exceptions.cs
mono/mini/interp/interp.c
mono/mini/interp/mintops.def
mono/mini/interp/transform.c

index d011fd3d042ff2cd8ef07f981dbe71fc1c74364a..d13385e35bb09348a29b3760622749223b02fbba 100644 (file)
@@ -2708,7 +2708,6 @@ class Tests
                public static Foo* pFoo;
        }
 
-       [Category ("!INTERPRETER")]
        /* MS.NET doesn't seem to throw in this case */
        public unsafe static int test_0_ldflda_null_pointer () {
                int* pi = &Foo.pFoo->i;
index 1df160cd2c7fce4c46a58e646a1280c30727b3e1..c37652d68ad1b1651adcdfdd751ae505b8ddcd9c 100644 (file)
@@ -2907,6 +2907,11 @@ array_constructed:
                                sp->data.p = mono_get_exception_null_reference ();
                        THROW_EX ((MonoException *)sp->data.p, ip);
                        MINT_IN_BREAK;
+               MINT_IN_CASE(MINT_LDFLDA_UNSAFE)
+                       o = sp [-1].data.p;
+                       sp[-1].data.p = (char *)o + * (guint16 *)(ip + 1);
+                       ip += 2;
+                       MINT_IN_BREAK;
                MINT_IN_CASE(MINT_LDFLDA)
                        o = sp [-1].data.p;
                        if (!o)
index 18128154af6ad06c4a8a412ff39c2f6db7787b08..f80f2a51acaf0dac3e43bfe9cf4294f2fd3a112d 100644 (file)
@@ -94,6 +94,7 @@ OPDEF(MINT_LDRMFLD, "ldrmfld", 2, MintOpFieldToken)
 OPDEF(MINT_LDRMFLD_VT, "ldrmfld.vt", 4, MintOpShortAndInt)
 
 OPDEF(MINT_LDFLDA, "ldflda", 2, MintOpUShortInt)
+OPDEF(MINT_LDFLDA_UNSAFE, "ldflda.unsafe", 2, MintOpUShortInt)
 
 OPDEF(MINT_STFLD_I1, "stfld.i1", 2, MintOpUShortInt)
 OPDEF(MINT_STFLD_U1, "stfld.u1", 2, MintOpUShortInt)
index 515c7da81ba93d9e956d4d6eedf6908107b3ab2d..31f4e0a0d0705db70ac9cc32c0e1ded4aec471ec 100644 (file)
@@ -1995,7 +1995,12 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, Mo
                                ADD_CODE (&td, MINT_LDSFLDA);
                                ADD_CODE (&td, get_data_item_index (&td, field));
                        } else {
-                               ADD_CODE (&td, MINT_LDFLDA);
+                               if ((td.sp - 1)->type == STACK_TYPE_O) {
+                                       ADD_CODE (&td, MINT_LDFLDA);
+                               } else {
+                                       g_assert ((td.sp -1)->type == STACK_TYPE_MP);
+                                       ADD_CODE (&td, MINT_LDFLDA_UNSAFE);
+                               }
                                ADD_CODE (&td, klass->valuetype ? field->offset - sizeof (MonoObject) : field->offset);
                        }
                        td.ip += 5;