[jit] Fix the casting between arrays with bounds and vectors even for special cased...
authorZoltan Varga <vargaz@gmail.com>
Mon, 3 Apr 2017 16:22:58 +0000 (12:22 -0400)
committerGitHub <noreply@github.com>
Mon, 3 Apr 2017 16:22:58 +0000 (12:22 -0400)
mono/mini/objects.cs
mono/mini/type-checking.c

index 21fd43e7d437f0ed5689d9d63c455e19add2be50..d8a7edd6dd8483d3628e9f99d80ab45bed0d35d6 100644 (file)
@@ -639,6 +639,7 @@ class Tests {
        public static int test_0_vector_array_cast () {
                Array arr1 = Array.CreateInstance (typeof (int), new int[] {1}, new int[] {0});
                Array arr2 = Array.CreateInstance (typeof (int), new int[] {1}, new int[] {10});
+               Array arr5 = Array.CreateInstance (typeof (string), new int[] {1}, new int[] {10});
 
                if (arr1.GetType () != typeof (int[]))
                        return 1;
@@ -659,6 +660,9 @@ class Tests {
 
                if (arr2 is int[])
                        return 4;
+               var as_object_arr = arr5 as object [];
+               if (as_object_arr != null)
+                       return 5;
 
                int [,] [] arr3 = new int [1, 1] [];
                object o = arr3;
index 812c430a634225259b2e584fda24a70789eb26df..96a03d97ffbf9d63bbea80a0bb3c8a06fbeb1bf3 100644 (file)
@@ -665,6 +665,14 @@ handle_isinst (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context_us
                        int rank_reg = alloc_preg (cfg);
                        int eclass_reg = alloc_preg (cfg);
 
+                       if ((klass->rank == 1) && (klass->byval_arg.type == MONO_TYPE_SZARRAY)) {
+                               /* Check that the object is a vector too */
+                               int bounds_reg = alloc_preg (cfg);
+                               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, bounds_reg, obj_reg, MONO_STRUCT_OFFSET (MonoArray, bounds));
+                               MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, bounds_reg, 0);
+                               MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBNE_UN, false_bb);
+                       }
+
                        g_assert (!context_used);
                        MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADU1_MEMBASE, rank_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, rank));
                        MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, rank_reg, klass->rank);
@@ -687,14 +695,6 @@ handle_isinst (MonoCompile *cfg, MonoClass *klass, MonoInst *src, int context_us
                        } else if (mono_class_is_interface (klass->cast_class)) {
                                mini_emit_iface_class_cast (cfg, eclass_reg, klass->cast_class, false_bb, is_null_bb);
                        } else {
-                               if ((klass->rank == 1) && (klass->byval_arg.type == MONO_TYPE_SZARRAY)) {
-                                       /* Check that the object is a vector too */
-                                       int bounds_reg = alloc_preg (cfg);
-                                       MONO_EMIT_NEW_LOAD_MEMBASE (cfg, bounds_reg, obj_reg, MONO_STRUCT_OFFSET (MonoArray, bounds));
-                                       MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, bounds_reg, 0);
-                                       MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBNE_UN, false_bb);
-                               }
-
                                /* the is_null_bb target simply copies the input register to the output */
                                mini_emit_isninst_cast (cfg, eclass_reg, klass->cast_class, false_bb, is_null_bb);
                        }