[jit] Use the right type when handling shared versions of RuntimeHelpers.IsReferenceO...
[mono.git] / mono / mini / gshared.cs
index 88f8c2ebb22b780a3c461daf2d8b62e6370f3e68..61402f7a4eca4f0314d21eb7918cf5e16ae02a00 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;
@@ -1659,6 +1677,8 @@ public class Tests
                                   uint i1, uint i2, uint i3, uint i4);
                int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
                                         BStruct s);
+               void Generic<T2> (T t, T2[] arr, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
+                                                 T2 i1, T2 i2, T2 i3, T2 i4);
        }
 
        class Foo3<T> : IFoo3<T> {
@@ -1690,6 +1710,13 @@ public class Tests
                                                        BStruct s) {
                        return s.a + s.b + s.c + s.d;
                }
+
+               public void Generic<T2> (T t, T2[] arr, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, T2 i1, T2 i2, T2 i3, T2 i4) {
+                       arr [0] = i1;
+                       arr [1] = i2;
+                       arr [2] = i3;
+                       arr [3] = i4;
+               }
        }
 
        // Passing small normal arguments on the stack
@@ -1713,6 +1740,10 @@ public class Tests
                int res6 = o.UInts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
                if (res6 != 10)
                        return 6;
+               int[] arr = new int [4];
+               o.Generic<int> (new EmptyStruct (), arr, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
+               if (arr [0] != 1 || arr [1] != 2 || arr [2] != 3 || arr [3] != 4)
+                       return 7;
                return 0;
        }
 
@@ -1907,6 +1938,64 @@ public class Tests
                bool success = zz == 0xAAAAAAAAAAAAAAAA;
                return success ? 20 : 1;
        }
+
+       void gsharedvt_try_at_offset_0<T> (ref T disposable)
+               where T : class, IDisposable {
+                       try {
+                               disposable.Dispose ();
+                       } finally {
+                               disposable = null;
+                       }
+               }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       static DateTimeOffset gsharedvt_vphi_inner<T> (T t) {
+               return DateTimeOffset.MinValue;
+       }
+
+       static DateTimeOffset gsharedvt_vphi<T> (T t) {
+               int[] arr = new int [10];
+
+               try {
+                       DateTimeOffset v;
+                       if (arr [0] == 0)
+                               v = gsharedvt_vphi_inner (t);
+                       else
+                               v = gsharedvt_vphi_inner (t);
+                       return v;
+               } catch {
+                       return DateTimeOffset.MinValue;
+               }
+       }
+
+       static int test_0_gsharedvt_vphi_volatile () {
+               gsharedvt_vphi (0);
+               return 0;
+       }
+
+       struct AStruct3<T1, T2, T3> {
+               T1 t1;
+               T2 t2;
+               T3 t3;
+       }
+
+       interface IFaceIsRef {
+               bool is_ref<T> ();
+       }
+
+       class ClassIsRef : IFaceIsRef {
+               [MethodImplAttribute (MethodImplOptions.NoInlining)]
+               public bool is_ref<T> () {
+                       return RuntimeHelpers.IsReferenceOrContainsReferences<T> ();
+               }
+       }
+
+       public static int test_0_isreference_intrins () {
+               IFaceIsRef iface = new ClassIsRef ();
+               Console.WriteLine ("X: " + iface.is_ref<AStruct3<int, int, int>> ());
+               Console.WriteLine ("X: " + iface.is_ref<AStruct3<string, int, int>> ());
+               return 0;
+       }
 }
 
 // #13191