using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; class Tests { struct TestStruct { public int i; public int j; public TestStruct (int i, int j) { this.i = i; this.j = j; } } class Enumerator : MyIEnumerator { T MyIEnumerator.Current { get { return default(T); } } bool MyIEnumerator.MoveNext () { return true; } } class Comparer : IComparer { bool IComparer.Compare (T x, T y) { return true; } } static int Main (string[] args) { return TestDriver.RunTests (typeof (Tests), args); } public static int test_1_nullable_unbox () { return Unbox (1).Value; } public static int test_1_nullable_unbox_null () { return Unbox (null).HasValue ? 0 : 1; } public static int test_1_nullable_box () { return (int) Box (1); } public static int test_1_nullable_box_null () { return Box (null) == null ? 1 : 0; } public static int test_1_isinst_nullable () { object o = 1; return (o is int?) ? 1 : 0; } public static int test_1_nullable_unbox_vtype () { return Unbox (new TestStruct (1, 2)).Value.i; } public static int test_1_nullable_unbox_null_vtype () { return Unbox (null).HasValue ? 0 : 1; } public static int test_1_nullable_box_vtype () { return ((TestStruct)(Box (new TestStruct (1, 2)))).i; } public static int test_1_nullable_box_null_vtype () { return Box (null) == null ? 1 : 0; } public static int test_1_isinst_nullable_vtype () { object o = new TestStruct (1, 2); return (o is TestStruct?) ? 1 : 0; } public static int test_0_nullable_normal_unbox () { int? i = 5; object o = i; // This uses unbox instead of unbox_any int? j = (int?)o; if (j != 5) return 1; return 0; } public static void stelem_any (T[] arr, T elem) { arr [0] = elem; } public static T ldelem_any (T[] arr) { return arr [0]; } public static int test_1_ldelem_stelem_any_int () { int[] arr = new int [3]; stelem_any (arr, 1); return ldelem_any (arr); } public static T return_ref (ref T t) { return t; } public static T ldelema_any (T[] arr) { return return_ref (ref arr [0]); } public static int test_0_ldelema () { string[] arr = new string [1]; arr [0] = "Hello"; if (ldelema_any (arr) == "Hello") return 0; else return 1; } public static T[,] newarr_multi () { return new T [1, 1]; } public static int test_0_newarr_multi_dim () { return newarr_multi ().GetType () == typeof (string[,]) ? 0 : 1; } interface ITest { void Foo (); } public static int test_0_iface_call_null_bug_77442 () { ITest test = null; try { test.Foo (); } catch (NullReferenceException) { return 0; } return 1; } public static int test_18_ldobj_stobj_generics () { GenericClass t = new GenericClass (); int i = 5; int j = 6; return t.ldobj_stobj (ref i, ref j) + i + j; } public static int test_5_ldelem_stelem_generics () { GenericClass t = new GenericClass (); TestStruct s = new TestStruct (5, 5); return t.ldelem_stelem (s).i; } public static int test_0_constrained_vtype_box () { GenericClass t = new GenericClass (); return t.toString (new TestStruct ()) == "Tests+TestStruct" ? 0 : 1; } public static int test_0_constrained_vtype () { GenericClass t = new GenericClass (); return t.toString (1234) == "1234" ? 0 : 1; } public static int test_0_constrained_reftype () { GenericClass t = new GenericClass (); return t.toString ("1234") == "1234" ? 0 : 1; } public static int test_0_box_brtrue_optimizations () { if (IsNull(5)) return 1; if (!IsNull(null)) return 1; return 0; } [Category ("!FULLAOT")] public static int test_0_generic_get_value_optimization_int () { int[] x = new int[] {100, 200}; if (GenericClass.Z (x, 0) != 100) return 2; if (GenericClass.Z (x, 1) != 200) return 3; return 0; } public static int test_0_generic_get_value_optimization_vtype () { TestStruct[] arr = new TestStruct[] { new TestStruct (100, 200), new TestStruct (300, 400) }; IEnumerator enumerator = GenericClass.Y (arr); TestStruct s; int sum = 0; while (enumerator.MoveNext ()) { s = enumerator.Current; sum += s.i + s.j; } if (sum != 1000) return 1; s = GenericClass.Z (arr, 0); if (s.i != 100 || s.j != 200) return 2; s = GenericClass.Z (arr, 1); if (s.i != 300 || s.j != 400) return 3; return 0; } public static int test_0_nullable_ldflda () { return GenericClass.BIsAClazz == false ? 0 : 1; } public struct GenericStruct { public T t; public GenericStruct (T t) { this.t = t; } } public class GenericClass { public T t; public GenericClass (T t) { this.t = t; } public GenericClass () { } public T ldobj_stobj (ref T t1, ref T t2) { t1 = t2; T t = t1; return t; } public T ldelem_stelem (T t) { T[] arr = new T [10]; arr [0] = t; return arr [0]; } public String toString (T t) { return t.ToString (); } public static IEnumerator Y (IEnumerable x) { return x.GetEnumerator (); } public static T Z (IList x, int index) { return x [index]; } protected static T NullB = default(T); private static Nullable _BIsA = null; public static bool BIsAClazz { get { _BIsA = false; return _BIsA.Value; } } } public class MRO : MarshalByRefObject { public GenericStruct struct_field; public GenericClass class_field; } public static int test_0_ldfld_stfld_mro () { MRO m = new MRO (); GenericStruct s = new GenericStruct (5); // This generates stfld m.struct_field = s; // This generates ldflda if (m.struct_field.t != 5) return 1; // This generates ldfld GenericStruct s2 = m.struct_field; if (s2.t != 5) return 2; if (m.struct_field.t != 5) return 3; m.class_field = new GenericClass (5); if (m.class_field.t != 5) return 4; return 0; } // FIXME: [Category ("!FULLAOT")] public static int test_0_generic_virtual_call_on_vtype_unbox () { object o = new Object (); IFoo h = new Handler(o); if (h.Bar () != o) return 1; else return 0; } public static int test_0_box_brtrue_opt () { Foo f = new Foo (5); f [123] = 5; return 0; } public static int test_0_box_brtrue_opt_regress_81102 () { if (new Foo(5).ToString () == "null") return 0; else return 1; } struct S { public int i; } public static int test_0_ldloca_initobj_opt () { if (new Foo (new S ()).get_default ().i != 0) return 1; if (new Foo (null).get_default () != null) return 2; return 0; } public static int test_0_variance_reflection () { // covariance on IEnumerator if (!typeof (MyIEnumerator).IsAssignableFrom (typeof (MyIEnumerator))) return 1; // covariance on IEnumerator and covariance on arrays if (!typeof (MyIEnumerator[]).IsAssignableFrom (typeof (MyIEnumerator[]))) return 2; // covariance and implemented interfaces if (!typeof (MyIEnumerator).IsAssignableFrom (typeof (Enumerator))) return 3; // contravariance on IComparer if (!typeof (IComparer).IsAssignableFrom (typeof (IComparer))) return 4; // contravariance on IComparer, contravariance on arrays if (!typeof (IComparer[]).IsAssignableFrom (typeof (IComparer[]))) return 5; // contravariance and interface inheritance if (!typeof (IComparer[]).IsAssignableFrom (typeof (IKeyComparer[]))) return 6; return 0; } public static int test_0_ldvirtftn_generic_method () { new Tests ().ldvirtftn (); return the_type == typeof (string) ? 0 : 1; } public static int test_0_throw_dead_this () { new Foo ("").throw_dead_this (); return 0; } struct S {} public static int test_0_inline_infinite_polymorphic_recursion () { f(0); return 0; } private static void f(int i) { if(i==42) f>(i); } // This cannot be made to work with full-aot, since there it is impossible to // statically determine that Foo.Bar is needed, the code only // references IFoo.Bar [Category ("!FULLAOT")] public static int test_0_generic_virtual_on_interfaces () { Foo.count1 = 0; Foo.count2 = 0; Foo.count3 = 0; IFoo f = new Foo (""); for (int i = 0; i < 1000; ++i) { f.Bar (); f.Bar (); f.NonGeneric (); } if (Foo.count1 != 1000) return 1; if (Foo.count2 != 1000) return 2; if (Foo.count3 != 1000) return 3; VirtualInterfaceCallFromGenericMethod (f); return 0; } //repro for #505375 [Category ("!FULLAOT")] public static int test_2_cprop_bug () { int idx = 0; int a = 1; var cmp = System.Collections.Generic.Comparer.Default ; if (cmp.Compare (a, 0) > 0) a = 0; do { idx++; } while (cmp.Compare (idx - 1, a) == 0); return idx; } enum MyEnumUlong : ulong { Value_2 = 2 } public static int test_0_regress_550964_constrained_enum_long () { MyEnumUlong a = MyEnumUlong.Value_2; MyEnumUlong b = MyEnumUlong.Value_2; return Pan (a, b) ? 0 : 1; } static bool Pan (T a, T b) { return a.Equals (b); } public class XElement { public string Value { get; set; } } public static int test_0_fullaot_linq () { var allWords = new XElement [] { new XElement { Value = "one" } }; var filteredWords = allWords.Where(kw => kw.Value.StartsWith("T")); return filteredWords.Count (); } public static int test_0_fullaot_comparer_t () { var l = new SortedList (); return l.Count; } public static int test_0_fullaot_comparer_t_2 () { var l = new Dictionary (); return l.Count; } static void enumerate (IEnumerable arr) { foreach (var o in arr) ; int c = ((ICollection)arr).Count; } /* Test that treating arrays as generic collections works with full-aot */ public static int test_0_fullaot_array_wrappers () { Tests[] arr = new Tests [10]; enumerate (arr); return 0; } static int cctor_count = 0; public abstract class Beta { static Beta() { cctor_count ++; } } public class Gamma : Beta { static Gamma() { } } // #519336 public static int test_2_generic_class_init_gshared_ctor () { new Gamma(); new Gamma(); return cctor_count; } static int cctor_count2 = 0; class ServiceController { static ServiceController () { cctor_count2 ++; } public ServiceController () { } } static ServiceController Create() { return new ServiceController(); } // #631409 public static int test_2_generic_class_init_gshared_ctor_from_gshared () { Create (); Create (); return cctor_count2; } public static Type get_type () { return typeof (T); } public static int test_0_gshared_delegate_rgctx () { Func t = new Func (get_type); if (t () == typeof (string)) return 0; else return 1; } // Creating a delegate from a generic method from gshared code public static int test_0_gshared_delegate_from_gshared () { if (gshared_delegate_from_gshared () != 0) return 1; if (gshared_delegate_from_gshared () != 0) return 2; return 0; } public static int gshared_delegate_from_gshared () { Func t = new Func (get_type); return t () == typeof (T) ? 0 : 1; } public static int test_0_marshalbyref_call_from_gshared_virt_elim () { /* Calling a virtual method from gshared code which is changed to a nonvirt call */ Class1 o = new Class1 (); o.Do (new Class2 ()); return 0; } class Pair { public static KeyValuePair make_pair (TKey key, TValue value) { return new KeyValuePair (key, value); } public delegate TRet Transform (TKey key, TValue value); } public static int test_0_bug_620864 () { var d = new Pair.Transform> (Pair.make_pair); var p = d ("FOO", typeof (int)); if (p.Key != "FOO" || p.Value != typeof (int)) return 1; return 0; } struct RecStruct { public void foo (RecStruct> baz) { } } public static int test_0_infinite_generic_recursion () { // Check that the AOT compile can deal with infinite generic recursion through // parameter types RecStruct bla; return 0; } struct FooStruct { } bool IsNull2 (object value) where T : struct { T? item = (T?) value; if (item.HasValue) return false; return true; } public static int test_0_full_aot_nullable_unbox_from_gshared_code () { if (!new Tests ().IsNull2 (null)) return 1; if (new Tests ().IsNull2 (new FooStruct ())) return 2; return 0; } public static int test_0_partial_sharing () { if (PartialShared1 (new List (), 1) != typeof (string)) return 1; if (PartialShared1 (new List (), 1) != typeof (Tests)) return 2; if (PartialShared2 (new List (), 1) != typeof (int)) return 3; if (PartialShared2 (new List (), 1) != typeof (int)) return 4; return 0; } public static int test_6_partial_sharing_linq () { var messages = new List (); messages.Add (new Message () { MessageID = 5 }); messages.Add (new Message () { MessageID = 6 }); return messages.Max(i => i.MessageID); } public static int test_0_partial_shared_method_in_nonshared_class () { var c = new Class1 (); return (c.Foo (5).GetType () == typeof (Class1)) ? 0 : 1; } class Message { public int MessageID { get; set; } } public static Type PartialShared1 (List list, K k) { return typeof (T); } public static Type PartialShared2 (List list, K k) { return typeof (K); } public class Class1 { public virtual void Do (Class2 t) { t.Foo (); } public virtual object Foo (T t) { return new Class1 (); } } public interface IFace1 { void Foo (); } public class Class2 : MarshalByRefObject, IFace1 { public void Foo () { } } public static void VirtualInterfaceCallFromGenericMethod (IFoo f) { f.Bar (); } public static Type the_type; public void ldvirtftn () { Foo binding = new Foo (default (T)); binding.GenericEvent += event_handler; binding.fire (); } public virtual void event_handler (Foo sender) { the_type = typeof (T); } public interface IFoo { void NonGeneric (); object Bar(); } public class Foo : IFoo { public Foo(T1 t1) { m_t1 = t1; } public override string ToString() { return Bar(m_t1 == null ? "null" : "null"); } public String Bar (String s) { return s; } public int this [T1 key] { set { if (key == null) throw new ArgumentNullException ("key"); } } public void throw_dead_this () { try { new SomeClass().ThrowAnException(); } catch { } } public T1 get_default () { return default (T1); } readonly T1 m_t1; public delegate void GenericEventHandler (Foo sender); public event GenericEventHandler GenericEvent; public void fire () { GenericEvent (this); } public static int count1, count2, count3; public void NonGeneric () { count3 ++; } public object Bar () { if (typeof (T) == typeof (int)) count1 ++; else if (typeof (T) == typeof (string)) count2 ++; return null; } } public class SomeClass { public void ThrowAnException() { throw new Exception ("Something went wrong"); } } struct Handler : IFoo { object o; public Handler(object o) { this.o = o; } public void NonGeneric () { } public object Bar() { return o; } } static bool IsNull (T t) { if (t == null) return true; else return false; } static object Box (T t) { return t; } static T Unbox (object o) { return (T) o; } interface IDefaultRetriever { T GetDefault(); } class DefaultRetriever : IDefaultRetriever { [MethodImpl(MethodImplOptions.Synchronized)] public T GetDefault() { return default(T); } } [Category ("!FULLAOT")] public static int test_0_regress_668095_synchronized_gshared () { return DoSomething (new DefaultRetriever ()); } static int DoSomething(IDefaultRetriever foo) { int result = foo.GetDefault(); return result; } }