using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; public partial class Tests { struct TestStruct { public int i; public int j; public TestStruct(int i, int j) { this.i = i; this.j = j; } } 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; } 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: 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 GenericsS { public int i; } public static int test_0_ldloca_initobj_opt() { if (new Foo(new GenericsS()).get_default().i != 0) return 1; if (new Foo(null).get_default() != null) return 2; 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 GenericsS { } 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 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; } public static int test_0_generic_virtual_on_interfaces_ref() { Foo.count1 = 0; Foo.count2 = 0; Foo.count3 = 0; Foo.count4 = 0; IFoo f = new Foo(""); for (int i = 0; i < 1000; ++i) { f.Bar(); f.Bar(); f.NonGeneric(); } if (Foo.count2 != 1000) return 2; if (Foo.count3 != 1000) return 3; if (Foo.count4 != 1000) return 4; return 0; } //repro for #505375 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 GenericsFooStruct { } 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 GenericsFooStruct())) 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, count4; public void NonGeneric() { count3++; } public object Bar() { if (typeof(T) == typeof(int)) count1++; else if (typeof(T) == typeof(string)) count2++; else if (typeof(T) == typeof(object)) count4++; 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); } } public static int test_0_regress_668095_synchronized_gshared() { return DoSomething(new DefaultRetriever()); } static int DoSomething(IDefaultRetriever foo) { int result = foo.GetDefault(); return result; } }