[jit] Fix target_type_is_incompatible to type check byref enums correctly.
authorRodrigo Kumpera <kumpera@gmail.com>
Mon, 16 Nov 2015 05:22:56 +0000 (00:22 -0500)
committerRodrigo Kumpera <kumpera@gmail.com>
Thu, 3 Mar 2016 00:05:49 +0000 (19:05 -0500)
mono/mini/method-to-ir.c

index bde9d416719fb71cc8654ce0a0bd446e05ab7aac..619f192d398f5176e958b8f771f75c6f3ca8eedb 100644 (file)
@@ -2210,17 +2210,18 @@ target_type_is_incompatible (MonoCompile *cfg, MonoType *target, MonoInst *arg)
        if (target->byref) {
                /* FIXME: check that the pointed to types match */
                if (arg->type == STACK_MP) {
-                       MonoClass *base_class = mono_class_from_mono_type (target);
-                       /* This is needed to handle gshared types + ldaddr */
-                       simple_type = mini_get_underlying_type (&base_class->byval_arg);
+                       if (cfg->verbose_level) printf ("ok\n");
+                       /* This is needed to handle gshared types + ldaddr. We lower the types so we can handle enums and other typedef-like types. */
+                       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 || arg->klass == mono_class_from_mono_type (simple_type))
+                       if (target->type == MONO_TYPE_I || target_class_lowered == source_class_lowered)
                                return 0;
 
                        /* Both are primitive type byrefs and the source points to a larger type that the destination */
-                       if (MONO_TYPE_IS_PRIMITIVE_SCALAR (target) && MONO_TYPE_IS_PRIMITIVE_SCALAR (&arg->klass->byval_arg) &&
-                               mono_class_instance_size (mono_class_from_mono_type (target)) <= mono_class_instance_size (arg->klass))
+                       if (MONO_TYPE_IS_PRIMITIVE_SCALAR (&target_class_lowered->byval_arg) && MONO_TYPE_IS_PRIMITIVE_SCALAR (&source_class_lowered->byval_arg) &&
+                               mono_class_instance_size (target_class_lowered) <= mono_class_instance_size (source_class_lowered))
                                return 0;
                        return 1;
                }