[jit] Fix support for gsharedvt constrained calls which return enums. Fixes #52600.
authorZoltan Varga <vargaz@gmail.com>
Sat, 18 Feb 2017 21:37:10 +0000 (16:37 -0500)
committerZoltan Varga <vargaz@gmail.com>
Sat, 18 Feb 2017 21:37:10 +0000 (16:37 -0500)
mono/mini/gshared.cs
mono/mini/method-to-ir.c

index 65151b07024e8d1a2199d9b76119cd07be48c527..e4323480388d18ed54d50e046ddc014aedb50217 100644 (file)
@@ -1026,7 +1026,7 @@ public class Tests
                return t.ToString ();
        }
 
-       enum AnEnum {
+       public enum AnEnum {
                One,
                Two
        };
@@ -1106,10 +1106,12 @@ public class Tests
 
        interface IConstrainedCalls {
                Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T: IReturnVType;
+               AnEnum enum_ret<T, T2>(T t, T2 t2) where T: IReturnVType;
        }
 
        public interface IReturnVType {
                Pair<int, int> return_vtype ();
+               AnEnum return_enum ();
        }
 
        public class CConstrainedCalls : IConstrainedCalls {
@@ -1117,12 +1119,20 @@ public class Tests
                public Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T : IReturnVType {
                        return t.return_vtype ();
                }
+
+               [MethodImplAttribute (MethodImplOptions.NoInlining)]
+               public AnEnum enum_ret<T, T2>(T t, T2 t2) where T : IReturnVType {
+                       return t.return_enum ();
+               }
        }
 
        class ReturnVType : IReturnVType {
                public Pair<int, int> return_vtype () {
                        return new Pair<int, int> () { First = 1, Second = 2 };
                }
+               public AnEnum return_enum () {
+                       return AnEnum.Two;
+               }
        }
 
        public static int test_0_constrained_vtype_ret () {
@@ -1133,6 +1143,14 @@ public class Tests
                return 0;
        }
 
+       public static int test_0_constrained_enum_ret () {
+               IConstrainedCalls c = new CConstrainedCalls ();
+               var r = c.enum_ret<ReturnVType, int> (new ReturnVType (), 1);
+               if (r != AnEnum.Two)
+                       return 1;
+               return 0;
+       }
+
        public struct Pair<T1, T2> {
                public T1 First;
                public T2 Second;
index 38ba5a241ec8e3d6373fd107c6513bccec045f9d..09bab4683ef57335c2209792745f8b4ea6546db0 100644 (file)
@@ -4450,7 +4450,7 @@ handle_constrained_gsharedvt_call (MonoCompile *cfg, MonoMethod *cmethod, MonoMe
         * pack the arguments into an array, and do the rest of the work in in an icall.
         */
        if (((cmethod->klass == mono_defaults.object_class) || mono_class_is_interface (cmethod->klass) || (!cmethod->klass->valuetype && cmethod->klass->image != mono_defaults.corlib)) &&
-               (MONO_TYPE_IS_VOID (fsig->ret) || MONO_TYPE_IS_PRIMITIVE (fsig->ret) || MONO_TYPE_IS_REFERENCE (fsig->ret) || MONO_TYPE_ISSTRUCT (fsig->ret) || mini_is_gsharedvt_type (fsig->ret)) &&
+               (MONO_TYPE_IS_VOID (fsig->ret) || MONO_TYPE_IS_PRIMITIVE (fsig->ret) || MONO_TYPE_IS_REFERENCE (fsig->ret) || MONO_TYPE_ISSTRUCT (fsig->ret) || mono_class_is_enum (mono_class_from_mono_type (fsig->ret)) || mini_is_gsharedvt_type (fsig->ret)) &&
                (fsig->param_count == 0 || (!fsig->hasthis && fsig->param_count == 1) || (fsig->param_count == 1 && (MONO_TYPE_IS_REFERENCE (fsig->params [0]) || fsig->params [0]->byref || mini_is_gsharedvt_type (fsig->params [0]))))) {
                MonoInst *args [16];
 
@@ -4502,7 +4502,7 @@ handle_constrained_gsharedvt_call (MonoCompile *cfg, MonoMethod *cmethod, MonoMe
 
                if (mini_is_gsharedvt_type (fsig->ret)) {
                        ins = handle_unbox_gsharedvt (cfg, mono_class_from_mono_type (fsig->ret), ins);
-               } else if (MONO_TYPE_IS_PRIMITIVE (fsig->ret) || MONO_TYPE_ISSTRUCT (fsig->ret)) {
+               } else if (MONO_TYPE_IS_PRIMITIVE (fsig->ret) || MONO_TYPE_ISSTRUCT (fsig->ret) || mono_class_is_enum (mono_class_from_mono_type (fsig->ret))) {
                        MonoInst *add;
 
                        /* Unbox */