Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / mini / generics.cs
index 9defe79f3cc9ff701d1c4bd16da6c91db5f49653..eafbd1c0e541c9187885ac412d98cdb863ae173e 100644 (file)
@@ -233,7 +233,42 @@ class Tests
                return 0;
        }
 
-       [Category ("!INTERPRETER")]
+       interface NonGenericInterface {
+               int return_field ();
+       }
+
+       interface GenericInterface<T> : NonGenericInterface {
+               T not_used ();
+       }
+
+       struct ImplementGenericInterface<T> : GenericInterface<T> {
+               public Object padding1;
+               public Object padding2;
+               public Object padding3;
+               public T[] arr_t;
+
+               public ImplementGenericInterface (T[] arr_t) {
+                       this.padding1 = null;
+                       this.padding2 = null;
+                       this.padding3 = null;
+                       this.arr_t = arr_t;
+               }
+
+               public T not_used () {
+                       return arr_t [0];
+               }
+
+               public int return_field () {
+                       return arr_t.Length;
+               }
+       }
+
+       public static int test_8_struct_implements_generic_interface () {
+               int[] arr = {1, 2, 3, 4};
+               NonGenericInterface s = new ImplementGenericInterface<int> (arr);
+               return s.return_field () + s.return_field ();
+       }
+
        public static int test_0_generic_get_value_optimization_vtype () {
                TestStruct[] arr = new TestStruct[] { new TestStruct (100, 200), new TestStruct (300, 400) };
                IEnumerator<TestStruct> enumerator = GenericClass<TestStruct>.Y (arr);
@@ -427,7 +462,6 @@ class Tests
        }
 #endif
 
-       [Category ("!INTERPRETER")]
        public static int test_0_ldvirtftn_generic_method () {
                new GenericsTests ().ldvirtftn<string> ();
 
@@ -454,7 +488,6 @@ class Tests
        // This cannot be made to work with full-aot, since there it is impossible to
        // statically determine that Foo<string>.Bar <int> is needed, the code only
        // references IFoo.Bar<int>
-       [Category ("!INTERPRETER")]
        [Category ("!FULLAOT")]
        public static int test_0_generic_virtual_on_interfaces () {
                Foo<string>.count1 = 0;
@@ -480,7 +513,6 @@ class Tests
                return 0;
        }
 
-       [Category ("!INTERPRETER")]
        public static int test_0_generic_virtual_on_interfaces_ref () {
                Foo<string>.count1 = 0;
                Foo<string>.count2 = 0;
@@ -520,7 +552,6 @@ class Tests
                Value_2 = 2
        }
 
-       [Category ("!INTERPRETER")]
        public static int test_0_regress_550964_constrained_enum_long () {
         MyEnumUlong a = MyEnumUlong.Value_2;
         MyEnumUlong b = MyEnumUlong.Value_2;
@@ -539,7 +570,6 @@ class Tests
                }
        }
 
-       [Category ("!INTERPRETER")]
        public static int test_0_fullaot_linq () {
                var allWords = new XElement [] { new XElement { Value = "one" } };
                var filteredWords = allWords.Where(kw => kw.Value.StartsWith("T"));
@@ -562,7 +592,6 @@ class Tests
                int c = ((ICollection<T>)arr).Count;
        }
 
-       [Category ("!INTERPRETER")]
        /* Test that treating arrays as generic collections works with full-aot */
        public static int test_0_fullaot_array_wrappers () {
                GenericsTests[] arr = new GenericsTests [10];
@@ -622,7 +651,6 @@ class Tests
                return typeof (T);
        }
 
-       [Category ("!INTERPRETER")]
        public static int test_0_gshared_delegate_rgctx () {
                Func<Type> t = new Func<Type> (get_type<string>);
 
@@ -632,7 +660,6 @@ class Tests
                        return 1;
        }
 
-       [Category ("!INTERPRETER")]
        // Creating a delegate from a generic method from gshared code
        public static int test_0_gshared_delegate_from_gshared () {
                if (gshared_delegate_from_gshared <object> () != 0)
@@ -664,7 +691,6 @@ class Tests
                public delegate TRet Transform<TRet> (TKey key, TValue value);
        }
 
-       [Category ("!INTERPRETER")]
        public static int test_0_bug_620864 () {
                var d = new Pair<string, Type>.Transform<KeyValuePair<string, Type>> (Pair<string, Type>.make_pair);
 
@@ -721,7 +747,6 @@ class Tests
                return 0;
        }
 
-       [Category ("!INTERPRETER")]
        [Category ("GSHAREDVT")]
        public static int test_6_partial_sharing_linq () {
                var messages = new List<Message> ();
@@ -732,7 +757,6 @@ class Tests
                return messages.Max(i => i.MessageID);
        }
 
-       [Category ("!INTERPRETER")]
        public static int test_0_partial_shared_method_in_nonshared_class () {
                var c = new Class1<double> ();
                return (c.Foo<string> (5).GetType () == typeof (Class1<string>)) ? 0 : 1;
@@ -909,7 +933,6 @@ class Tests
                }
        }
 
-       [Category ("!INTERPRETER")]
        [Category ("!FULLAOT")]
        [Category ("!BITCODE")]
        public static int test_0_regress_668095_synchronized_gshared () {
@@ -928,7 +951,6 @@ class Tests
                }
        }
 
-       [Category ("!INTERPRETER")]
        [Category ("GSHAREDVT")]
        static int test_0_synchronized_gshared () {
                var c = new SyncClass<string> ();
@@ -965,7 +987,6 @@ class Tests
        }
 
        // #2155
-       [Category ("!INTERPRETER")]
        [Category ("GSHAREDVT")]
        public static int test_0_fullaot_sflda_cctor () {
                List<Doc> documents = new List<Doc>();
@@ -991,7 +1012,6 @@ class Tests
     static List<A> sources = new List<A>();
 
        // #6112
-       [Category ("!INTERPRETER")]
     public static int test_0_fullaot_imt () {
         sources.Add(null);
         sources.Add(null);
@@ -1013,7 +1033,6 @@ class Tests
        class BClass : AClass {
        }
 
-       [Category ("!INTERPRETER")]
        public static int test_0_fullaot_variant_iface () {
                var arr = new BClass [10];
                var enumerable = (IEnumerable<AClass>)arr;
@@ -1045,7 +1064,6 @@ class Tests
                }
        }
 
-       [Category ("!INTERPRETER")]
        public static int test_1_regress_constrained_iface_call_7571 () {
         var r = new Record [10];
         Foo2<Record>.Extract (r);
@@ -1056,7 +1074,6 @@ class Tests
                Val = 1
        }
 
-       [Category ("!INTERPRETER")]
        public static int test_0_regress_constrained_iface_call_enum () {
                var r = new ConstrainedEnum [10];
                return Foo3<ConstrainedEnum>.CompareTo (r);
@@ -1116,7 +1133,6 @@ class Tests
        }
 #endif
 
-       [Category ("!INTERPRETER")]
        public static int test_0_delegate_callvirt_fullaot () {
                Func<string> f = delegate () { return "A"; };
         var f2 = (Func<Func<string>, string>)Delegate.CreateDelegate (typeof
@@ -1199,7 +1215,6 @@ class Tests
                return t.GetHashCode ();
        }
 
-       [Category ("!INTERPRETER")]
        public static int test_0_constrained_partial_sharing () {
                string s;
 
@@ -1256,7 +1271,6 @@ class Tests
 
        static object delegate_8_args_res;
 
-       [Category ("!INTERPRETER")]
        public static int test_0_delegate_8_args () {
                delegate_8_args_res = null;
                Action<string, string, string, string, string, string, string,
@@ -1294,6 +1308,89 @@ class Tests
                c.throw_catch_t ();
                return 0;
        }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static bool is_ref_or_contains_refs<T> () {
+               return RuntimeHelpers.IsReferenceOrContainsReferences<T> ();
+       }
+
+       class IsRefClass<T> {
+               [MethodImplAttribute (MethodImplOptions.NoInlining)]
+               public bool is_ref () {
+                       return RuntimeHelpers.IsReferenceOrContainsReferences<T> ();
+               }
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static bool is_ref_or_contains_refs_gen_ref<T> () {
+               return RuntimeHelpers.IsReferenceOrContainsReferences<GenStruct<T>> ();
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static bool is_ref_or_contains_refs_gen_noref<T> () {
+               return RuntimeHelpers.IsReferenceOrContainsReferences<NoRefGenStruct<T>> ();
+       }
+
+       struct GenStruct<T> {
+               T t;
+       }
+
+       struct NoRefGenStruct<T> {
+       }
+
+       struct RefStruct {
+               string s;
+       }
+
+       struct NestedRefStruct {
+               RefStruct r;
+       }
+
+       struct NoRefStruct {
+               int i;
+       }
+
+       struct AStruct3<T1, T2, T3> {
+               T1 t1;
+               T2 t2;
+               T3 t3;
+       }
+
+       public static int test_0_isreference_intrins () {
+               if (RuntimeHelpers.IsReferenceOrContainsReferences<int> ())
+                       return 1;
+               if (!RuntimeHelpers.IsReferenceOrContainsReferences<string> ())
+                       return 2;
+               if (!RuntimeHelpers.IsReferenceOrContainsReferences<RefStruct> ())
+                       return 3;
+               if (!RuntimeHelpers.IsReferenceOrContainsReferences<NestedRefStruct> ())
+                       return 4;
+               if (RuntimeHelpers.IsReferenceOrContainsReferences<NoRefStruct> ())
+                       return 5;
+               // Generic code
+               if (is_ref_or_contains_refs<int> ())
+                       return 6;
+               // Shared code
+               if (!is_ref_or_contains_refs<string> ())
+                       return 7;
+               // Complex type from shared code
+               if (!is_ref_or_contains_refs_gen_ref<string> ())
+                       return 8;
+               if (is_ref_or_contains_refs_gen_ref<int> ())
+                       return 9;
+               if (is_ref_or_contains_refs_gen_noref<string> ())
+                       return 10;
+
+               // Complex type from shared class method
+               var c1 = new IsRefClass<AStruct3<int, int, int>> ();
+               if (c1.is_ref ())
+                       return 11;
+               var c2 = new IsRefClass<AStruct3<string, int, int>> ();
+               if (!c2.is_ref ())
+                       return 12;
+
+               return 0;
+       }
 }
 
 #if !__MOBILE__