2 using System.Reflection;
3 using System.Runtime.CompilerServices;
6 * Regression tests for the mono JIT.
8 * Each test needs to be of the form:
10 * public static int test_<result>_<name> ();
12 * where <result> is an integer (the value that needs to be returned by
13 * the method to make it pass.
14 * <name> is a user-displayed name used to identify the test.
16 * The tests can be driven in two ways:
17 * *) running the program directly: Main() uses reflection to find and invoke
18 * the test methods (this is useful mostly to check that the tests are correct)
19 * *) with the --regression switch of the jit (this is the preferred way since
20 * all the tests will be run with optimizations on and off)
22 * The reflection logic could be moved to a .dll since we need at least another
23 * regression test file written in IL code to have better control on how
29 public static int Main () {
30 return TestDriver.RunTests (typeof (Tests));
33 public static int test_0_catch () {
34 Exception x = new Exception ();
38 } catch (Exception e) {
45 public static int test_0_finally_without_exc () {
50 } catch (Exception e) {
59 public static int test_0_finally () {
63 throw new Exception ();
64 } catch (Exception e) {
72 public static int test_0_nested_finally () {
87 public static int test_0_byte_cast () {
100 } catch (OverflowException) {
114 } catch (OverflowException) {
129 } catch (OverflowException) {
143 } catch (OverflowException) {
157 } catch (OverflowException) {
171 } catch (OverflowException) {
185 } catch (OverflowException) {
199 } catch (OverflowException) {
213 } catch (OverflowException) {
227 } catch (OverflowException) {
241 } catch (OverflowException) {
255 } catch (OverflowException) {
270 catch (OverflowException) {
281 public static int test_0_sbyte_cast () {
293 } catch (OverflowException) {
307 } catch (OverflowException) {
321 } catch (OverflowException) {
335 } catch (OverflowException) {
349 } catch (OverflowException) {
363 } catch (OverflowException) {
377 } catch (OverflowException) {
391 } catch (OverflowException) {
405 } catch (OverflowException) {
419 } catch (OverflowException) {
433 } catch (OverflowException) {
447 } catch (OverflowException) {
461 } catch (OverflowException) {
475 } catch (OverflowException) {
489 } catch (OverflowException) {
503 } catch (OverflowException) {
517 } catch (OverflowException) {
531 } catch (OverflowException) {
545 } catch (OverflowException) {
559 } catch (OverflowException) {
574 catch (OverflowException) {
585 public static int test_0_ushort_cast () {
593 a = System.UInt16.MaxValue;
598 } catch (OverflowException) {
610 } catch (OverflowException) {
617 a = System.UInt16.MaxValue + 1;
622 } catch (OverflowException) {
634 } catch (OverflowException) {
646 } catch (OverflowException) {
653 double d = System.UInt16.MaxValue;
658 } catch (OverflowException) {
670 } catch (OverflowException) {
677 double d = System.UInt16.MaxValue + 1.0;
682 } catch (OverflowException) {
689 l = System.UInt16.MaxValue;
694 } catch (OverflowException) {
706 } catch (OverflowException) {
713 l = System.UInt16.MaxValue + 1;
718 } catch (OverflowException) {
730 } catch (OverflowException) {
742 } catch (OverflowException) {
751 public static int test_0_short_cast () {
758 a = System.UInt16.MaxValue;
763 } catch (OverflowException) {
775 } catch (OverflowException) {
782 a = System.Int16.MaxValue + 1;
787 } catch (OverflowException) {
794 a = System.Int16.MinValue - 1;
799 } catch (OverflowException) {
811 } catch (OverflowException) {
818 a = System.Int16.MinValue;
823 } catch (OverflowException) {
830 a = System.Int16.MaxValue;
835 } catch (OverflowException) {
842 a = System.Int16.MaxValue + 1;
847 } catch (OverflowException) {
854 double d = System.Int16.MaxValue;
859 } catch (OverflowException) {
866 double d = System.Int16.MinValue;
871 } catch (OverflowException) {
878 double d = System.Int16.MaxValue + 1.0;
883 } catch (OverflowException) {
890 double d = System.Int16.MinValue - 1.0;
895 } catch (OverflowException) {
902 l = System.Int16.MaxValue + 1;
907 } catch (OverflowException) {
914 l = System.Int16.MaxValue;
919 } catch (OverflowException) {
926 l = System.Int16.MinValue - 1;
931 } catch (OverflowException) {
939 l = System.Int16.MinValue;
944 } catch (OverflowException) {
951 l = 0x00000000ffffffff;
956 } catch (OverflowException) {
968 } catch (OverflowException) {
977 public static int test_0_int_cast () {
983 double d = System.Int32.MaxValue + 1.0;
988 } catch (OverflowException) {
995 double d = System.Int32.MaxValue;
1000 } catch (OverflowException) {
1008 double d = System.Int32.MinValue;
1013 } catch (OverflowException) {
1021 double d = System.Int32.MinValue - 1.0;
1026 } catch (OverflowException) {
1033 l = System.Int32.MaxValue + (long)1;
1038 } catch (OverflowException) {
1045 l = System.Int32.MaxValue;
1050 } catch (OverflowException) {
1058 l = System.Int32.MinValue;
1063 } catch (OverflowException) {
1071 l = System.Int32.MinValue - (long)1;
1076 } catch (OverflowException) {
1083 uint ui = System.UInt32.MaxValue;
1089 catch (OverflowException) {
1096 ulong ul = (long)(System.Int32.MaxValue) + 1;
1102 catch (OverflowException) {
1109 ulong ul = UInt64.MaxValue;
1115 catch (OverflowException) {
1132 public static int test_0_uint_cast () {
1138 double d = System.UInt32.MaxValue;
1143 } catch (OverflowException) {
1150 double d = System.UInt32.MaxValue + 1.0;
1155 } catch (OverflowException) {
1162 double d = System.UInt32.MinValue;
1167 } catch (OverflowException) {
1174 double d = System.UInt32.MinValue - 1.0;
1179 } catch (OverflowException) {
1186 l = System.UInt32.MaxValue;
1191 } catch (OverflowException) {
1198 l = System.UInt32.MaxValue + (long)1;
1203 } catch (OverflowException) {
1210 l = System.UInt32.MinValue;
1215 } catch (OverflowException) {
1222 l = System.UInt32.MinValue - (long)1;
1227 } catch (OverflowException) {
1240 catch (OverflowException) {
1257 public static int test_0_long_cast () {
1260 * These tests depend on properties of x86 fp arithmetic so they won't work
1261 * on other platforms.
1268 double d = System.Int64.MaxValue - 512.0;
1273 } catch (OverflowException) {
1280 double d = System.Int64.MaxValue - 513.0;
1285 } catch (OverflowException) {
1292 double d = System.Int64.MinValue - 1024.0;
1297 } catch (OverflowException) {
1304 double d = System.Int64.MinValue - 1025.0;
1309 } catch (OverflowException) {
1327 public static int test_0_ulong_cast () {
1332 * These tests depend on properties of x86 fp arithmetic so they won't work
1333 * on other platforms.
1338 double d = System.UInt64.MaxValue - 1024.0;
1343 } catch (OverflowException) {
1350 double d = System.UInt64.MaxValue - 1025.0;
1355 } catch (OverflowException) {
1368 } catch (OverflowException) {
1380 } catch (OverflowException) {
1401 catch (OverflowException) {
1408 int i = Int32.MinValue;
1414 catch (OverflowException) {
1423 public static int test_0_simple_double_casts () {
1425 double d = 0xffffffff;
1427 if ((uint)d != 4294967295)
1431 * These tests depend on properties of x86 fp arithmetic so they won't work
1432 * on other platforms.
1435 d = 0xffffffffffffffff;
1449 if ((ushort)d != 0xffff)
1452 if ((byte)d != 0xff)
1458 public static int test_0_div_zero () {
1467 } catch (DivideByZeroException) {
1476 } catch (DivideByZeroException) {
1487 } catch (DivideByZeroException) {
1488 /* wrong exception */
1489 } catch (OverflowException) {
1500 } catch (DivideByZeroException) {
1501 /* wrong exception */
1502 } catch (OverflowException) {
1511 public static int return_55 () {
1515 public static int test_0_cfold_div_zero () {
1516 // Test that constant folding doesn't cause division by zero exceptions
1517 if (return_55 () != return_55 ()) {
1536 public static int test_0_udiv_zero () {
1545 } catch (DivideByZeroException) {
1554 } catch (DivideByZeroException) {
1563 public static int test_0_long_div_zero () {
1572 } catch (DivideByZeroException) {
1581 } catch (DivideByZeroException) {
1592 } catch (DivideByZeroException) {
1593 /* wrong exception */
1594 } catch (ArithmeticException) {
1605 } catch (DivideByZeroException) {
1606 /* wrong exception */
1607 } catch (ArithmeticException) {
1616 public static int test_0_ulong_div_zero () {
1625 } catch (DivideByZeroException) {
1634 } catch (DivideByZeroException) {
1643 public static int test_0_float_div_zero () {
1652 } catch (DivideByZeroException) {
1661 } catch (DivideByZeroException) {
1670 public static int test_0_invalid_unbox () {
1673 object o = "Some string";
1677 // Illegal conversion; o contains a string not an int
1679 } catch (Exception e) {
1687 // Test that double[] can't be cast to double (bug #46027)
1688 public static int test_0_invalid_unbox_arrays () {
1689 double[] d1 = { 1.0 };
1690 double[][] d2 = { d1 };
1694 foreach (double d in a) {
1698 catch (InvalidCastException e) {
1703 /* bug# 42190, at least mcs generates a leave for the return that
1704 * jumps out of multiple exception clauses: we used to execute just
1705 * one enclosing finally block.
1707 public static int finally_level;
1708 static void do_something () {
1721 public static int test_2_multiple_finally_clauses () {
1724 if (finally_level == 1)
1729 public static int test_3_checked_cast_un () {
1730 ulong i = 0x8000000034000000;
1734 checked { j = (long)i; }
1735 } catch (OverflowException) {
1744 public static int test_4_checked_cast () {
1748 unchecked { i = (long)0x8000000034000000;};
1750 checked { j = (ulong)i; }
1751 } catch (OverflowException) {
1760 static readonly int[] mul_dim_results = new int[] {
1761 0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8,
1762 1, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8,
1766 5, 0, 5, 1, 5, 2, 5, 3, 5, 4, 5, 5, 5, 6, 5, 7, 5, 8,
1767 6, 0, 6, 1, 6, 2, 6, 3, 6, 4, 6, 5, 6, 6, 6, 7, 6, 8,
1768 7, 0, 7, 1, 7, 2, 7, 3, 7, 4, 7, 5, 7, 6, 7, 7, 7, 8,
1771 public static int test_0_multi_dim_array_access () {
1772 int [,] a = System.Array.CreateInstance (typeof (int),
1773 new int [] {3,6}, new int [] {2,2 }) as int[,];
1776 for (x = 0; x < 8; ++x) {
1777 for (y = 0; y < 9; ++y) {
1778 bool got_ex = false;
1785 if (result_idx >= mul_dim_results.Length)
1787 if (mul_dim_results [result_idx] != x || mul_dim_results [result_idx + 1] != y) {
1788 return result_idx + 1;
1794 if (result_idx == mul_dim_results.Length)
1799 static void helper_out_obj (out object o) {
1800 o = (object)"buddy";
1803 static void helper_out_string (out string o) {
1807 public static int test_2_array_mismatch () {
1808 string[] a = { "hello", "world" };
1810 bool passed = false;
1813 helper_out_obj (out b [1]);
1814 } catch (ArrayTypeMismatchException) {
1819 helper_out_string (out a [1]);
1820 if (a [1] != "buddy")
1825 public static int test_0_ovf1 () {
1830 ulong a = UInt64.MaxValue - 1;
1839 public static int test_1_ovf2 () {
1844 ulong a = UInt64.MaxValue;
1853 public static int test_0_ovf3 () {
1856 long a = Int64.MaxValue - 1;
1867 public static int test_1_ovf4 () {
1870 long a = Int64.MaxValue;
1881 public static int test_0_ovf5 () {
1884 ulong a = UInt64.MaxValue - 1;
1895 public static int test_1_ovf6 () {
1898 ulong a = UInt64.MaxValue;
1909 public static int test_0_ovf7 () {
1912 long a = Int64.MinValue + 1;
1923 public static int test_1_ovf8 () {
1926 long a = Int64.MinValue;
1937 public static int test_0_ovf9 () {
1940 ulong a = UInt64.MinValue + 1;
1951 public static int test_1_ovf10 () {
1954 ulong a = UInt64.MinValue;
1965 public static int test_0_ovf11 () {
1968 int a = Int32.MinValue + 1;
1979 public static int test_1_ovf12 () {
1982 int a = Int32.MinValue;
1993 public static int test_0_ovf13 () {
2007 public static int test_1_ovf14 () {
2021 public static int test_0_ovf15 () {
2035 public static int test_1_ovf16 () {
2049 public static int test_0_ovf17 () {
2061 public static int test_0_ovf18 () {
2075 public static int test_1_ovf19 () {
2089 public static int test_0_ovf20 () {
2094 ulong a = 0xffffffffff;
2095 ulong t = a*0x0ffffff;
2103 public static int test_1_ovf21 () {
2106 ulong a = 0xffffffffff;
2109 ulong t = a*0x0fffffff;
2117 public static int test_1_ovf22 () {
2120 long a = Int64.MinValue;
2132 public static int test_1_ovf23 () {
2136 long b = Int64.MinValue;
2148 public static int i;
2151 throw new Exception ("Ugh!");
2154 public static int DoSomething () {
2159 public static int test_0_exception_in_cctor () {
2161 Broken.DoSomething ();
2163 catch (TypeInitializationException) {
2164 // This will only happen once even if --regression is used
2169 public static int test_5_regalloc () {
2173 for (i = 0; i < 10; ++i) {
2175 throw new Exception ();
2183 // Check that variables written in catch clauses are volatile
2186 throw new Exception ();
2197 throw new Exception ();
2211 public static void rethrow () {
2213 throw new ApplicationException();
2214 } catch (ApplicationException) {
2216 throw new OverflowException();
2217 } catch (Exception) {
2223 // Test that a rethrow rethrows the correct exception
2224 public static int test_0_rethrow_nested () {
2227 } catch (OverflowException) {
2229 } catch (Exception) {
2235 /* MarshalByRefObject prevents the methods from being inlined */
2236 class ThrowClass : MarshalByRefObject {
2237 public static void rethrow1 () {
2238 throw new Exception ();
2241 public static void rethrow2 () {
2243 /* This disables tailcall opts */
2244 Console.WriteLine ();
2248 public static int test_0_rethrow_stacktrace () {
2249 // Check that rethrowing an exception preserves the original stack trace
2252 ThrowClass.rethrow2 ();
2254 catch (Exception ex) {
2255 // Check that each catch clause has its own exception variable
2256 // If not, the throw below will overwrite the exception used
2259 throw new DivideByZeroException ();
2261 catch (Exception foo) {
2267 catch (Exception ex) {
2268 if (ex.StackTrace.IndexOf ("rethrow2") != -1)
2276 class Face : IFace {}
2278 public static int test_1_array_mismatch_2 () {
2280 object [] o = new Face [1];
2283 } catch (ArrayTypeMismatchException) {
2288 public static int test_1_array_mismatch_3 () {
2290 object [] o = new IFace [1];
2293 } catch (ArrayTypeMismatchException) {
2298 public static int test_1_array_mismatch_4 () {
2300 object [][] o = new Face [5] [];
2301 o [0] = new object [5];
2304 } catch (ArrayTypeMismatchException) {
2309 public static int test_0_array_size () {
2314 int[] mem1 = new int [Int32.MaxValue];
2316 catch (OutOfMemoryException e) {
2324 int[,] mem2 = new int [Int32.MaxValue, Int32.MaxValue];
2326 catch (OutOfMemoryException e) {
2336 int i, j, k, l, m, n;
2339 static IntPtr[] addr;
2341 static unsafe void throw_func (int i, S s) {
2342 addr [i] = new IntPtr (&i);
2343 throw new Exception ();
2346 /* Test that arguments are correctly popped off the stack during unwinding */
2347 /* FIXME: Fails on x86 when llvm is enabled (#5432) */
2349 public static int test_0_stack_unwind () {
2350 addr = new IntPtr [1000];
2352 for (int j = 0; j < 1000; j++) {
2359 return (addr [0].ToInt64 () - addr [100].ToInt64 () < 100) ? 0 : 1;
2363 static unsafe void get_sp (int i) {
2364 addr [i] = new IntPtr (&i);
2367 /* Test that the arguments to the throw trampoline are correctly popped off the stack */
2368 public static int test_0_throw_unwind () {
2369 addr = new IntPtr [1000];
2371 for (int j = 0; j < 1000; j++) {
2374 throw new Exception ();
2379 return (addr [0].ToInt64 () - addr [100].ToInt64 () < 100) ? 0 : 1;
2382 public static int test_0_regress_73242 () {
2383 int [] arr = new int [10];
2384 for (int i = 0; i < 10; ++i)
2387 throw new Exception ();
2394 public static int test_0_nullref () {
2398 } catch (NullReferenceException e) {
2404 public int amethod () {
2408 public static int test_0_nonvirt_nullref_at_clause_start () {
2412 } catch (NullReferenceException) {
2419 public static int throw_only () {
2420 throw new Exception ();
2423 [MethodImpl(MethodImplOptions.NoInlining)]
2424 public static int throw_only2 () {
2425 return throw_only ();
2428 public static int test_0_inline_throw_only () {
2430 return throw_only2 ();
2432 catch (Exception ex) {
2437 public static string GetText (string s) {
2441 public static int throw_only_gettext () {
2442 throw new Exception (GetText ("FOO"));
2445 public static int test_0_inline_throw_only_gettext () {
2448 o = throw_only_gettext ();
2450 catch (Exception ex) {
2454 return o != null ? 0 : 1;
2458 public static int test_0_throw_to_branch_opt_outer_clause () {
2463 string [] files = new string[1];
2465 string s = files[2];
2472 return (i == 1) ? 0 : 1;
2476 public static int test_0_try_inside_finally_cmov_opt () {
2477 bool Reconect = false;
2479 object o = new object ();
2483 catch (Exception ExCon) {
2489 catch (Exception Last) {
2493 if (Reconect == true) {
2496 catch (Exception ex) {
2504 public static int test_0_inline_throw () {
2513 // for llvm, the end bblock is unreachable
2514 public static int inline_throw1 (int i) {
2516 throw new Exception ();
2518 return inline_throw2 (i);
2521 public static int inline_throw2 (int i) {
2522 throw new Exception ();
2526 public static int test_0_lmf_filter () {
2528 // The invoke calls a runtime-invoke wrapper which has a filter clause
2529 typeof (Tests).GetMethod ("lmf_filter").Invoke (null, new object [] { });
2530 } catch (TargetInvocationException) {
2535 public static void lmf_filter () {
2540 throw new NotImplementedException ();
2544 public static void Connect () {
2546 throw new Exception();
2549 public static void Stop () {
2557 private static void do_raise () {
2558 throw new System.Exception ();
2561 private static int int_func (int i) {
2566 public static int test_8_local_deadce_causes () {
2573 } catch (System.Exception) {
2579 public static int test_0_except_opt_two_clauses () {
2582 uint ui = (uint)size;
2585 uint v = ui * (uint)4;
2587 } catch (OverflowException e) {
2589 } catch (Exception) {
2598 public virtual long Method()
2600 throw new Exception();
2605 public static int test_100_long_vars_in_clauses_initlocals_opt () {
2606 Child c = new Child();
2616 public object AnObj;
2619 public static void DoSomething (ref object o) {
2622 public static int test_0_ldflda_null () {
2626 DoSomething (ref a.AnObj);
2627 } catch (NullReferenceException) {
2638 public static Foo* pFoo;
2641 /* MS.NET doesn't seem to throw in this case */
2642 public unsafe static int test_0_ldflda_null_pointer () {
2643 int* pi = &Foo.pFoo->i;
2648 static int test_0_try_clause_in_finally_clause_regalloc () {
2649 // Fill up registers with values
2650 object a = new object ();
2651 object[] arr1 = new object [1];
2652 object[] arr2 = new object [1];
2653 object[] arr3 = new object [1];
2654 object[] arr4 = new object [1];
2655 object[] arr5 = new object [1];
2657 for (int i = 0; i < 10; ++i)
2659 for (int i = 0; i < 10; ++i)
2661 for (int i = 0; i < 10; ++i)
2663 for (int i = 0; i < 10; ++i)
2665 for (int i = 0; i < 10; ++i)
2670 try_clause_in_finally_clause_regalloc_inner (out res);
2671 } catch (Exception) {
2676 public static object Throw () {
2677 for (int i = 0; i < 10; ++i)
2679 throw new Exception ();
2682 static void try_clause_in_finally_clause_regalloc_inner (out int res) {
2688 } catch (Exception) {
2689 /* Make sure this doesn't branch to the finally */
2690 throw new DivideByZeroException ();
2693 /* Make sure o is register allocated */
2706 } catch (DivideByZeroException) {
2711 public static bool t_1835_inner () {
2713 if (a) throw new Exception();
2717 [MethodImpl(MethodImplOptions.NoInlining)]
2718 public static bool t_1835_inner_2 () {
2719 bool b = t_1835_inner ();
2723 public static int test_0_inline_retval_throw_in_branch_1835 () {