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
35 public static int Main (string[] args) {
36 return TestDriver.RunTests (typeof (Tests), args);
40 public static int test_0_catch () {
41 Exception x = new Exception ();
45 } catch (Exception e) {
52 public static int test_0_finally_without_exc () {
57 } catch (Exception e) {
66 public static int test_0_finally () {
70 throw new Exception ();
71 } catch (Exception e) {
79 public static int test_0_nested_finally () {
94 public static int test_0_byte_cast () {
107 } catch (OverflowException) {
121 } catch (OverflowException) {
136 } catch (OverflowException) {
150 } catch (OverflowException) {
164 } catch (OverflowException) {
178 } catch (OverflowException) {
192 } catch (OverflowException) {
206 } catch (OverflowException) {
220 } catch (OverflowException) {
234 } catch (OverflowException) {
248 } catch (OverflowException) {
262 } catch (OverflowException) {
277 catch (OverflowException) {
288 public static int test_0_sbyte_cast () {
300 } catch (OverflowException) {
314 } catch (OverflowException) {
328 } catch (OverflowException) {
342 } catch (OverflowException) {
356 } catch (OverflowException) {
370 } catch (OverflowException) {
384 } catch (OverflowException) {
398 } catch (OverflowException) {
412 } catch (OverflowException) {
426 } catch (OverflowException) {
440 } catch (OverflowException) {
454 } catch (OverflowException) {
468 } catch (OverflowException) {
482 } catch (OverflowException) {
496 } catch (OverflowException) {
510 } catch (OverflowException) {
524 } catch (OverflowException) {
538 } catch (OverflowException) {
552 } catch (OverflowException) {
566 } catch (OverflowException) {
581 catch (OverflowException) {
592 public static int test_0_ushort_cast () {
600 a = System.UInt16.MaxValue;
605 } catch (OverflowException) {
617 } catch (OverflowException) {
624 a = System.UInt16.MaxValue + 1;
629 } catch (OverflowException) {
641 } catch (OverflowException) {
653 } catch (OverflowException) {
660 double d = System.UInt16.MaxValue;
665 } catch (OverflowException) {
677 } catch (OverflowException) {
684 double d = System.UInt16.MaxValue + 1.0;
689 } catch (OverflowException) {
696 l = System.UInt16.MaxValue;
701 } catch (OverflowException) {
713 } catch (OverflowException) {
720 l = System.UInt16.MaxValue + 1;
725 } catch (OverflowException) {
737 } catch (OverflowException) {
749 } catch (OverflowException) {
758 public static int test_0_short_cast () {
765 a = System.UInt16.MaxValue;
770 } catch (OverflowException) {
782 } catch (OverflowException) {
789 a = System.Int16.MaxValue + 1;
794 } catch (OverflowException) {
801 a = System.Int16.MinValue - 1;
806 } catch (OverflowException) {
818 } catch (OverflowException) {
825 a = System.Int16.MinValue;
830 } catch (OverflowException) {
837 a = System.Int16.MaxValue;
842 } catch (OverflowException) {
849 a = System.Int16.MaxValue + 1;
854 } catch (OverflowException) {
861 double d = System.Int16.MaxValue;
866 } catch (OverflowException) {
873 double d = System.Int16.MinValue;
878 } catch (OverflowException) {
885 double d = System.Int16.MaxValue + 1.0;
890 } catch (OverflowException) {
897 double d = System.Int16.MinValue - 1.0;
902 } catch (OverflowException) {
909 l = System.Int16.MaxValue + 1;
914 } catch (OverflowException) {
921 l = System.Int16.MaxValue;
926 } catch (OverflowException) {
933 l = System.Int16.MinValue - 1;
938 } catch (OverflowException) {
946 l = System.Int16.MinValue;
951 } catch (OverflowException) {
958 l = 0x00000000ffffffff;
963 } catch (OverflowException) {
975 } catch (OverflowException) {
984 public static int test_0_int_cast () {
990 double d = System.Int32.MaxValue + 1.0;
995 } catch (OverflowException) {
1002 double d = System.Int32.MaxValue;
1007 } catch (OverflowException) {
1015 double d = System.Int32.MinValue;
1020 } catch (OverflowException) {
1028 double d = System.Int32.MinValue - 1.0;
1033 } catch (OverflowException) {
1040 l = System.Int32.MaxValue + (long)1;
1045 } catch (OverflowException) {
1052 l = System.Int32.MaxValue;
1057 } catch (OverflowException) {
1065 l = System.Int32.MinValue;
1070 } catch (OverflowException) {
1078 l = System.Int32.MinValue - (long)1;
1083 } catch (OverflowException) {
1090 uint ui = System.UInt32.MaxValue;
1096 catch (OverflowException) {
1103 ulong ul = (long)(System.Int32.MaxValue) + 1;
1109 catch (OverflowException) {
1116 ulong ul = UInt64.MaxValue;
1122 catch (OverflowException) {
1139 public static int test_0_uint_cast () {
1145 double d = System.UInt32.MaxValue;
1150 } catch (OverflowException) {
1157 double d = System.UInt32.MaxValue + 1.0;
1162 } catch (OverflowException) {
1169 double d = System.UInt32.MinValue;
1174 } catch (OverflowException) {
1181 double d = System.UInt32.MinValue - 1.0;
1186 } catch (OverflowException) {
1193 l = System.UInt32.MaxValue;
1198 } catch (OverflowException) {
1205 l = System.UInt32.MaxValue + (long)1;
1210 } catch (OverflowException) {
1217 l = System.UInt32.MinValue;
1222 } catch (OverflowException) {
1229 l = System.UInt32.MinValue - (long)1;
1234 } catch (OverflowException) {
1247 catch (OverflowException) {
1264 public static int test_0_long_cast () {
1267 * These tests depend on properties of x86 fp arithmetic so they won't work
1268 * on other platforms.
1275 double d = System.Int64.MaxValue - 512.0;
1280 } catch (OverflowException) {
1287 double d = System.Int64.MaxValue - 513.0;
1292 } catch (OverflowException) {
1299 double d = System.Int64.MinValue - 1024.0;
1304 } catch (OverflowException) {
1311 double d = System.Int64.MinValue - 1025.0;
1316 } catch (OverflowException) {
1334 public static int test_0_ulong_cast () {
1339 * These tests depend on properties of x86 fp arithmetic so they won't work
1340 * on other platforms.
1345 double d = System.UInt64.MaxValue - 1024.0;
1350 } catch (OverflowException) {
1357 double d = System.UInt64.MaxValue - 1025.0;
1362 } catch (OverflowException) {
1375 } catch (OverflowException) {
1387 } catch (OverflowException) {
1408 catch (OverflowException) {
1415 int i = Int32.MinValue;
1421 catch (OverflowException) {
1430 public static int test_0_simple_double_casts () {
1432 double d = 0xffffffff;
1434 if ((uint)d != 4294967295)
1438 * These tests depend on properties of x86 fp arithmetic so they won't work
1439 * on other platforms.
1442 d = 0xffffffffffffffff;
1456 if ((ushort)d != 0xffff)
1459 if ((byte)d != 0xff)
1465 [Category ("NaClDisable")]
1466 public static int test_0_div_zero () {
1475 } catch (DivideByZeroException) {
1484 } catch (DivideByZeroException) {
1495 } catch (DivideByZeroException) {
1496 /* wrong exception */
1497 } catch (OverflowException) {
1508 } catch (DivideByZeroException) {
1509 /* wrong exception */
1510 } catch (OverflowException) {
1519 public static int return_55 () {
1523 public static int test_0_cfold_div_zero () {
1524 // Test that constant folding doesn't cause division by zero exceptions
1525 if (return_55 () != return_55 ()) {
1544 public static int test_0_udiv_zero () {
1553 } catch (DivideByZeroException) {
1562 } catch (DivideByZeroException) {
1571 [Category ("NaClDisable")]
1572 public static int test_0_long_div_zero () {
1581 } catch (DivideByZeroException) {
1590 } catch (DivideByZeroException) {
1601 } catch (DivideByZeroException) {
1602 /* wrong exception */
1603 } catch (ArithmeticException) {
1614 } catch (DivideByZeroException) {
1615 /* wrong exception */
1616 } catch (ArithmeticException) {
1625 public static int test_0_ulong_div_zero () {
1634 } catch (DivideByZeroException) {
1643 } catch (DivideByZeroException) {
1652 public static int test_0_float_div_zero () {
1661 } catch (DivideByZeroException) {
1670 } catch (DivideByZeroException) {
1679 public static int test_0_invalid_unbox () {
1682 object o = "Some string";
1686 // Illegal conversion; o contains a string not an int
1688 } catch (Exception e) {
1696 // Test that double[] can't be cast to double (bug #46027)
1697 public static int test_0_invalid_unbox_arrays () {
1698 double[] d1 = { 1.0 };
1699 double[][] d2 = { d1 };
1703 foreach (double d in a) {
1707 catch (InvalidCastException e) {
1712 /* bug# 42190, at least mcs generates a leave for the return that
1713 * jumps out of multiple exception clauses: we used to execute just
1714 * one enclosing finally block.
1716 public static int finally_level;
1717 static void do_something () {
1730 public static int test_2_multiple_finally_clauses () {
1733 if (finally_level == 1)
1738 public static int test_3_checked_cast_un () {
1739 ulong i = 0x8000000034000000;
1743 checked { j = (long)i; }
1744 } catch (OverflowException) {
1753 public static int test_4_checked_cast () {
1757 unchecked { i = (long)0x8000000034000000;};
1759 checked { j = (ulong)i; }
1760 } catch (OverflowException) {
1769 static readonly int[] mul_dim_results = new int[] {
1770 0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8,
1771 1, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8,
1775 5, 0, 5, 1, 5, 2, 5, 3, 5, 4, 5, 5, 5, 6, 5, 7, 5, 8,
1776 6, 0, 6, 1, 6, 2, 6, 3, 6, 4, 6, 5, 6, 6, 6, 7, 6, 8,
1777 7, 0, 7, 1, 7, 2, 7, 3, 7, 4, 7, 5, 7, 6, 7, 7, 7, 8,
1780 public static int test_0_multi_dim_array_access () {
1781 int [,] a = System.Array.CreateInstance (typeof (int),
1782 new int [] {3,6}, new int [] {2,2 }) as int[,];
1785 for (x = 0; x < 8; ++x) {
1786 for (y = 0; y < 9; ++y) {
1787 bool got_ex = false;
1794 if (result_idx >= mul_dim_results.Length)
1796 if (mul_dim_results [result_idx] != x || mul_dim_results [result_idx + 1] != y) {
1797 return result_idx + 1;
1803 if (result_idx == mul_dim_results.Length)
1808 static void helper_out_obj (out object o) {
1809 o = (object)"buddy";
1812 static void helper_out_string (out string o) {
1816 public static int test_2_array_mismatch () {
1817 string[] a = { "hello", "world" };
1819 bool passed = false;
1822 helper_out_obj (out b [1]);
1823 } catch (ArrayTypeMismatchException) {
1828 helper_out_string (out a [1]);
1829 if (a [1] != "buddy")
1834 public static int test_0_ovf1 () {
1839 ulong a = UInt64.MaxValue - 1;
1848 public static int test_1_ovf2 () {
1853 ulong a = UInt64.MaxValue;
1862 public static int test_0_ovf3 () {
1865 long a = Int64.MaxValue - 1;
1876 public static int test_1_ovf4 () {
1879 long a = Int64.MaxValue;
1890 public static int test_0_ovf5 () {
1893 ulong a = UInt64.MaxValue - 1;
1904 public static int test_1_ovf6 () {
1907 ulong a = UInt64.MaxValue;
1918 public static int test_0_ovf7 () {
1921 long a = Int64.MinValue + 1;
1932 public static int test_1_ovf8 () {
1935 long a = Int64.MinValue;
1946 public static int test_0_ovf9 () {
1949 ulong a = UInt64.MinValue + 1;
1960 public static int test_1_ovf10 () {
1963 ulong a = UInt64.MinValue;
1974 public static int test_0_ovf11 () {
1977 int a = Int32.MinValue + 1;
1988 public static int test_1_ovf12 () {
1991 int a = Int32.MinValue;
2002 public static int test_0_ovf13 () {
2016 public static int test_1_ovf14 () {
2030 public static int test_0_ovf15 () {
2044 public static int test_1_ovf16 () {
2058 public static int test_0_ovf17 () {
2070 public static int test_0_ovf18 () {
2084 public static int test_1_ovf19 () {
2098 public static int test_0_ovf20 () {
2103 ulong a = 0xffffffffff;
2104 ulong t = a*0x0ffffff;
2112 public static int test_1_ovf21 () {
2115 ulong a = 0xffffffffff;
2118 ulong t = a*0x0fffffff;
2126 public static int test_1_ovf22 () {
2129 long a = Int64.MinValue;
2141 public static int test_1_ovf23 () {
2145 long b = Int64.MinValue;
2157 public static int i;
2160 throw new Exception ("Ugh!");
2163 public static int DoSomething () {
2168 public static int test_0_exception_in_cctor () {
2170 Broken.DoSomething ();
2172 catch (TypeInitializationException) {
2173 // This will only happen once even if --regression is used
2178 public static int test_5_regalloc () {
2182 for (i = 0; i < 10; ++i) {
2184 throw new Exception ();
2192 // Check that variables written in catch clauses are volatile
2195 throw new Exception ();
2206 throw new Exception ();
2220 public static void rethrow () {
2222 throw new ApplicationException();
2223 } catch (ApplicationException) {
2225 throw new OverflowException();
2226 } catch (Exception) {
2232 // Test that a rethrow rethrows the correct exception
2233 public static int test_0_rethrow_nested () {
2236 } catch (OverflowException) {
2238 } catch (Exception) {
2244 /* MarshalByRefObject prevents the methods from being inlined */
2245 class ThrowClass : MarshalByRefObject {
2246 public static void rethrow1 () {
2247 throw new Exception ();
2250 public static void rethrow2 () {
2252 /* This disables tailcall opts */
2253 Console.WriteLine ();
2257 public static int test_0_rethrow_stacktrace () {
2258 // Check that rethrowing an exception preserves the original stack trace
2261 ThrowClass.rethrow2 ();
2263 catch (Exception ex) {
2264 // Check that each catch clause has its own exception variable
2265 // If not, the throw below will overwrite the exception used
2268 throw new DivideByZeroException ();
2270 catch (Exception foo) {
2276 catch (Exception ex) {
2277 if (ex.StackTrace.IndexOf ("rethrow2") != -1)
2285 class Face : IFace {}
2287 public static int test_1_array_mismatch_2 () {
2289 object [] o = new Face [1];
2292 } catch (ArrayTypeMismatchException) {
2297 public static int test_1_array_mismatch_3 () {
2299 object [] o = new IFace [1];
2302 } catch (ArrayTypeMismatchException) {
2307 public static int test_1_array_mismatch_4 () {
2309 object [][] o = new Face [5] [];
2310 o [0] = new object [5];
2313 } catch (ArrayTypeMismatchException) {
2318 public static int test_0_array_size () {
2323 int[] mem1 = new int [Int32.MaxValue];
2325 catch (OutOfMemoryException e) {
2333 int[,] mem2 = new int [Int32.MaxValue, Int32.MaxValue];
2335 catch (OutOfMemoryException e) {
2345 int i, j, k, l, m, n;
2348 static IntPtr[] addr;
2350 static unsafe void throw_func (int i, S s) {
2351 addr [i] = new IntPtr (&i);
2352 throw new Exception ();
2355 /* Test that arguments are correctly popped off the stack during unwinding */
2356 /* FIXME: Fails on x86 when llvm is enabled (#5432) */
2358 public static int test_0_stack_unwind () {
2359 addr = new IntPtr [1000];
2361 for (int j = 0; j < 1000; j++) {
2368 return (addr [0].ToInt64 () - addr [100].ToInt64 () < 100) ? 0 : 1;
2372 static unsafe void get_sp (int i) {
2373 addr [i] = new IntPtr (&i);
2376 /* Test that the arguments to the throw trampoline are correctly popped off the stack */
2377 public static int test_0_throw_unwind () {
2378 addr = new IntPtr [1000];
2380 for (int j = 0; j < 1000; j++) {
2383 throw new Exception ();
2388 return (addr [0].ToInt64 () - addr [100].ToInt64 () < 100) ? 0 : 1;
2391 public static int test_0_regress_73242 () {
2392 int [] arr = new int [10];
2393 for (int i = 0; i < 10; ++i)
2396 throw new Exception ();
2403 public static int test_0_nullref () {
2407 } catch (NullReferenceException e) {
2413 public int amethod () {
2417 public static int test_0_nonvirt_nullref_at_clause_start () {
2418 ExceptionTests t = null;
2421 } catch (NullReferenceException) {
2428 public static int throw_only () {
2429 throw new Exception ();
2432 [MethodImpl(MethodImplOptions.NoInlining)]
2433 public static int throw_only2 () {
2434 return throw_only ();
2437 public static int test_0_inline_throw_only () {
2439 return throw_only2 ();
2441 catch (Exception ex) {
2446 public static string GetText (string s) {
2450 public static int throw_only_gettext () {
2451 throw new Exception (GetText ("FOO"));
2454 public static int test_0_inline_throw_only_gettext () {
2457 o = throw_only_gettext ();
2459 catch (Exception ex) {
2463 return o != null ? 0 : 1;
2467 public static int test_0_throw_to_branch_opt_outer_clause () {
2472 string [] files = new string[1];
2474 string s = files[2];
2481 return (i == 1) ? 0 : 1;
2485 public static int test_0_try_inside_finally_cmov_opt () {
2486 bool Reconect = false;
2488 object o = new object ();
2492 catch (Exception ExCon) {
2498 catch (Exception Last) {
2502 if (Reconect == true) {
2505 catch (Exception ex) {
2513 public static int test_0_inline_throw () {
2522 // for llvm, the end bblock is unreachable
2523 public static int inline_throw1 (int i) {
2525 throw new Exception ();
2527 return inline_throw2 (i);
2530 public static int inline_throw2 (int i) {
2531 throw new Exception ();
2535 public static int test_0_lmf_filter () {
2537 // The invoke calls a runtime-invoke wrapper which has a filter clause
2539 typeof (ExceptionTests).GetMethod ("lmf_filter").Invoke (null, new object [] { });
2541 typeof (Tests).GetMethod ("lmf_filter").Invoke (null, new object [] { });
2543 } catch (TargetInvocationException) {
2548 public static void lmf_filter () {
2553 throw new NotImplementedException ();
2557 public static void Connect () {
2559 throw new Exception();
2562 public static void Stop () {
2570 private static void do_raise () {
2571 throw new System.Exception ();
2574 private static int int_func (int i) {
2579 public static int test_8_local_deadce_causes () {
2586 } catch (System.Exception) {
2592 public static int test_0_except_opt_two_clauses () {
2595 uint ui = (uint)size;
2598 uint v = ui * (uint)4;
2600 } catch (OverflowException e) {
2602 } catch (Exception) {
2611 public virtual long Method()
2613 throw new Exception();
2618 public static int test_100_long_vars_in_clauses_initlocals_opt () {
2619 Child c = new Child();
2629 public object AnObj;
2632 public static void DoSomething (ref object o) {
2635 public static int test_0_ldflda_null () {
2639 DoSomething (ref a.AnObj);
2640 } catch (NullReferenceException) {
2651 public static Foo* pFoo;
2654 /* MS.NET doesn't seem to throw in this case */
2655 public unsafe static int test_0_ldflda_null_pointer () {
2656 int* pi = &Foo.pFoo->i;
2661 static int test_0_try_clause_in_finally_clause_regalloc () {
2662 // Fill up registers with values
2663 object a = new object ();
2664 object[] arr1 = new object [1];
2665 object[] arr2 = new object [1];
2666 object[] arr3 = new object [1];
2667 object[] arr4 = new object [1];
2668 object[] arr5 = new object [1];
2670 for (int i = 0; i < 10; ++i)
2672 for (int i = 0; i < 10; ++i)
2674 for (int i = 0; i < 10; ++i)
2676 for (int i = 0; i < 10; ++i)
2678 for (int i = 0; i < 10; ++i)
2683 try_clause_in_finally_clause_regalloc_inner (out res);
2684 } catch (Exception) {
2689 public static object Throw () {
2690 for (int i = 0; i < 10; ++i)
2692 throw new Exception ();
2695 static void try_clause_in_finally_clause_regalloc_inner (out int res) {
2701 } catch (Exception) {
2702 /* Make sure this doesn't branch to the finally */
2703 throw new DivideByZeroException ();
2706 /* Make sure o is register allocated */
2719 } catch (DivideByZeroException) {
2724 public static bool t_1835_inner () {
2726 if (a) throw new Exception();
2730 [MethodImpl(MethodImplOptions.NoInlining)]
2731 public static bool t_1835_inner_2 () {
2732 bool b = t_1835_inner ();
2736 public static int test_0_inline_retval_throw_in_branch_1835 () {
2747 class ExceptionTests : Tests