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 [Category ("!INTERPRETER")]
985 public static int test_0_int_cast () {
991 double d = System.Int32.MaxValue + 1.0;
996 } catch (OverflowException) {
1003 double d = System.Int32.MaxValue;
1008 } catch (OverflowException) {
1016 double d = System.Int32.MinValue;
1021 } catch (OverflowException) {
1029 double d = System.Int32.MinValue - 1.0;
1034 } catch (OverflowException) {
1041 l = System.Int32.MaxValue + (long)1;
1046 } catch (OverflowException) {
1053 l = System.Int32.MaxValue;
1058 } catch (OverflowException) {
1066 l = System.Int32.MinValue;
1071 } catch (OverflowException) {
1079 l = System.Int32.MinValue - (long)1;
1084 } catch (OverflowException) {
1091 uint ui = System.UInt32.MaxValue;
1097 catch (OverflowException) {
1104 ulong ul = (long)(System.Int32.MaxValue) + 1;
1110 catch (OverflowException) {
1117 ulong ul = UInt64.MaxValue;
1123 catch (OverflowException) {
1140 public static int test_0_uint_cast () {
1146 double d = System.UInt32.MaxValue;
1151 } catch (OverflowException) {
1158 double d = System.UInt32.MaxValue + 1.0;
1163 } catch (OverflowException) {
1170 double d = System.UInt32.MinValue;
1175 } catch (OverflowException) {
1182 double d = System.UInt32.MinValue - 1.0;
1187 } catch (OverflowException) {
1194 l = System.UInt32.MaxValue;
1199 } catch (OverflowException) {
1206 l = System.UInt32.MaxValue + (long)1;
1211 } catch (OverflowException) {
1218 l = System.UInt32.MinValue;
1223 } catch (OverflowException) {
1230 l = System.UInt32.MinValue - (long)1;
1235 } catch (OverflowException) {
1248 catch (OverflowException) {
1265 public static int test_0_long_cast () {
1268 * These tests depend on properties of x86 fp arithmetic so they won't work
1269 * on other platforms.
1276 double d = System.Int64.MaxValue - 512.0;
1281 } catch (OverflowException) {
1288 double d = System.Int64.MaxValue - 513.0;
1293 } catch (OverflowException) {
1300 double d = System.Int64.MinValue - 1024.0;
1305 } catch (OverflowException) {
1312 double d = System.Int64.MinValue - 1025.0;
1317 } catch (OverflowException) {
1335 public static int test_0_ulong_cast () {
1340 * These tests depend on properties of x86 fp arithmetic so they won't work
1341 * on other platforms.
1346 double d = System.UInt64.MaxValue - 1024.0;
1351 } catch (OverflowException) {
1358 double d = System.UInt64.MaxValue - 1025.0;
1363 } catch (OverflowException) {
1376 } catch (OverflowException) {
1388 } catch (OverflowException) {
1409 catch (OverflowException) {
1416 int i = Int32.MinValue;
1422 catch (OverflowException) {
1431 public static int test_0_simple_double_casts () {
1433 double d = 0xffffffff;
1435 if ((uint)d != 4294967295)
1439 * These tests depend on properties of x86 fp arithmetic so they won't work
1440 * on other platforms.
1443 d = 0xffffffffffffffff;
1457 if ((ushort)d != 0xffff)
1460 if ((byte)d != 0xff)
1466 [Category ("!INTERPRETER")]
1467 [Category ("NaClDisable")]
1468 public static int test_0_div_zero () {
1477 } catch (DivideByZeroException) {
1486 } catch (DivideByZeroException) {
1497 } catch (DivideByZeroException) {
1498 /* wrong exception */
1499 } catch (OverflowException) {
1510 } catch (DivideByZeroException) {
1511 /* wrong exception */
1512 } catch (OverflowException) {
1521 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1522 static void dummy () {
1525 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1526 static int div_zero_llvm_inner (int i) {
1528 // This call make use avoid the 'handler without invoke' restriction in the llvm backend
1531 } catch (Exception ex) {
1536 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1537 static long div_zero_llvm_inner_long (long l) {
1541 } catch (Exception ex) {
1546 public static int test_0_div_zero_llvm () {
1547 long r = div_zero_llvm_inner (0);
1550 r = div_zero_llvm_inner_long (0);
1556 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1557 static int div_overflow_llvm_inner (int i) {
1560 return Int32.MinValue / i;
1561 } catch (Exception ex) {
1566 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1567 static long div_overflow_llvm_inner_long (long l) {
1570 return Int64.MinValue / l;
1571 } catch (Exception ex) {
1576 public static int test_0_div_overflow_llvm () {
1577 long r = div_overflow_llvm_inner (-1);
1580 r = div_overflow_llvm_inner_long ((long)-1);
1586 public static int return_55 () {
1590 public static int test_0_cfold_div_zero () {
1591 // Test that constant folding doesn't cause division by zero exceptions
1592 if (return_55 () != return_55 ()) {
1611 public static int test_0_udiv_zero () {
1620 } catch (DivideByZeroException) {
1629 } catch (DivideByZeroException) {
1638 [Category ("!INTERPRETER")]
1639 [Category ("NaClDisable")]
1640 public static int test_0_long_div_zero () {
1649 } catch (DivideByZeroException) {
1658 } catch (DivideByZeroException) {
1669 } catch (DivideByZeroException) {
1670 /* wrong exception */
1671 } catch (ArithmeticException) {
1682 } catch (DivideByZeroException) {
1683 /* wrong exception */
1684 } catch (ArithmeticException) {
1693 public static int test_0_ulong_div_zero () {
1702 } catch (DivideByZeroException) {
1711 } catch (DivideByZeroException) {
1720 public static int test_0_float_div_zero () {
1729 } catch (DivideByZeroException) {
1738 } catch (DivideByZeroException) {
1747 public static int test_0_invalid_unbox () {
1750 object o = "Some string";
1754 // Illegal conversion; o contains a string not an int
1756 } catch (Exception e) {
1764 // Test that double[] can't be cast to double (bug #46027)
1765 public static int test_0_invalid_unbox_arrays () {
1766 double[] d1 = { 1.0 };
1767 double[][] d2 = { d1 };
1771 foreach (double d in a) {
1775 catch (InvalidCastException e) {
1780 /* bug# 42190, at least mcs generates a leave for the return that
1781 * jumps out of multiple exception clauses: we used to execute just
1782 * one enclosing finally block.
1784 public static int finally_level;
1785 static void do_something () {
1798 public static int test_2_multiple_finally_clauses () {
1801 if (finally_level == 1)
1806 [Category ("!INTERPRETER")]
1807 public static int test_3_checked_cast_un () {
1808 ulong i = 0x8000000034000000;
1812 checked { j = (long)i; }
1813 } catch (OverflowException) {
1822 [Category ("!INTERPRETER")]
1823 public static int test_4_checked_cast () {
1827 unchecked { i = (long)0x8000000034000000;};
1829 checked { j = (ulong)i; }
1830 } catch (OverflowException) {
1839 static readonly int[] mul_dim_results = new int[] {
1840 0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8,
1841 1, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8,
1845 5, 0, 5, 1, 5, 2, 5, 3, 5, 4, 5, 5, 5, 6, 5, 7, 5, 8,
1846 6, 0, 6, 1, 6, 2, 6, 3, 6, 4, 6, 5, 6, 6, 6, 7, 6, 8,
1847 7, 0, 7, 1, 7, 2, 7, 3, 7, 4, 7, 5, 7, 6, 7, 7, 7, 8,
1850 [Category ("!INTERPRETER")]
1851 public static int test_0_multi_dim_array_access () {
1852 int [,] a = System.Array.CreateInstance (typeof (int),
1853 new int [] {3,6}, new int [] {2,2 }) as int[,];
1856 for (x = 0; x < 8; ++x) {
1857 for (y = 0; y < 9; ++y) {
1858 bool got_ex = false;
1865 if (result_idx >= mul_dim_results.Length)
1867 if (mul_dim_results [result_idx] != x || mul_dim_results [result_idx + 1] != y) {
1868 return result_idx + 1;
1874 if (result_idx == mul_dim_results.Length)
1879 static void helper_out_obj (out object o) {
1880 o = (object)"buddy";
1883 static void helper_out_string (out string o) {
1887 [Category ("!INTERPRETER")]
1888 public static int test_2_array_mismatch () {
1889 string[] a = { "hello", "world" };
1891 bool passed = false;
1894 helper_out_obj (out b [1]);
1895 } catch (ArrayTypeMismatchException) {
1900 helper_out_string (out a [1]);
1901 if (a [1] != "buddy")
1906 public static int test_0_ovf1 () {
1911 ulong a = UInt64.MaxValue - 1;
1920 public static int test_1_ovf2 () {
1925 ulong a = UInt64.MaxValue;
1934 public static int test_0_ovf3 () {
1937 long a = Int64.MaxValue - 1;
1948 public static int test_1_ovf4 () {
1951 long a = Int64.MaxValue;
1962 public static int test_0_ovf5 () {
1965 ulong a = UInt64.MaxValue - 1;
1976 public static int test_1_ovf6 () {
1979 ulong a = UInt64.MaxValue;
1990 public static int test_0_ovf7 () {
1993 long a = Int64.MinValue + 1;
2004 public static int test_1_ovf8 () {
2007 long a = Int64.MinValue;
2018 public static int test_0_ovf9 () {
2021 ulong a = UInt64.MinValue + 1;
2032 public static int test_1_ovf10 () {
2035 ulong a = UInt64.MinValue;
2046 public static int test_0_ovf11 () {
2049 int a = Int32.MinValue + 1;
2060 public static int test_1_ovf12 () {
2063 int a = Int32.MinValue;
2074 public static int test_0_ovf13 () {
2088 public static int test_1_ovf14 () {
2102 public static int test_0_ovf15 () {
2116 public static int test_1_ovf16 () {
2130 public static int test_0_ovf17 () {
2142 public static int test_0_ovf18 () {
2156 public static int test_1_ovf19 () {
2170 public static int test_0_ovf20 () {
2175 ulong a = 0xffffffffff;
2176 ulong t = a*0x0ffffff;
2184 public static int test_1_ovf21 () {
2187 ulong a = 0xffffffffff;
2190 ulong t = a*0x0fffffff;
2198 public static int test_1_ovf22 () {
2201 long a = Int64.MinValue;
2213 public static int test_1_ovf23 () {
2217 long b = Int64.MinValue;
2229 public static int i;
2232 throw new Exception ("Ugh!");
2235 public static int DoSomething () {
2240 [Category ("!INTERPRETER")]
2241 public static int test_0_exception_in_cctor () {
2243 Broken.DoSomething ();
2245 catch (TypeInitializationException) {
2246 // This will only happen once even if --regression is used
2251 public static int test_5_regalloc () {
2255 for (i = 0; i < 10; ++i) {
2257 throw new Exception ();
2265 // Check that variables written in catch clauses are volatile
2268 throw new Exception ();
2279 throw new Exception ();
2293 public static void rethrow () {
2295 throw new ApplicationException();
2296 } catch (ApplicationException) {
2298 throw new OverflowException();
2299 } catch (Exception) {
2305 // Test that a rethrow rethrows the correct exception
2306 public static int test_0_rethrow_nested () {
2309 } catch (OverflowException) {
2311 } catch (Exception) {
2317 [MethodImplAttribute (MethodImplOptions.NoInlining)]
2318 public static void rethrow1 () {
2319 throw new Exception ();
2322 [MethodImplAttribute (MethodImplOptions.NoInlining)]
2323 public static void rethrow2 () {
2325 /* This disables tailcall opts */
2326 Console.WriteLine ();
2329 [Category ("!INTERPRETER")]
2330 [Category ("!BITCODE")]
2331 public static int test_0_rethrow_stacktrace () {
2332 // Check that rethrowing an exception preserves the original stack trace
2337 catch (Exception ex) {
2338 // Check that each catch clause has its own exception variable
2339 // If not, the throw below will overwrite the exception used
2342 throw new DivideByZeroException ();
2344 catch (Exception foo) {
2350 catch (Exception ex) {
2351 if (ex.StackTrace.IndexOf ("rethrow2") != -1)
2359 class Face : IFace {}
2361 public static int test_1_array_mismatch_2 () {
2363 object [] o = new Face [1];
2366 } catch (ArrayTypeMismatchException) {
2371 public static int test_1_array_mismatch_3 () {
2373 object [] o = new IFace [1];
2376 } catch (ArrayTypeMismatchException) {
2381 public static int test_1_array_mismatch_4 () {
2383 object [][] o = new Face [5] [];
2384 o [0] = new object [5];
2387 } catch (ArrayTypeMismatchException) {
2392 [Category ("!INTERPRETER")]
2393 public static int test_0_array_size () {
2398 int[,] mem2 = new int [Int32.MaxValue, Int32.MaxValue];
2400 catch (OutOfMemoryException e) {
2410 int i, j, k, l, m, n;
2413 static IntPtr[] addr;
2415 static unsafe void throw_func (int i, S s) {
2416 addr [i] = new IntPtr (&i);
2417 throw new Exception ();
2420 /* Test that arguments are correctly popped off the stack during unwinding */
2421 /* FIXME: Fails on x86 when llvm is enabled (#5432) */
2423 public static int test_0_stack_unwind () {
2424 addr = new IntPtr [1000];
2426 for (int j = 0; j < 1000; j++) {
2433 return (addr [0].ToInt64 () - addr [100].ToInt64 () < 100) ? 0 : 1;
2437 static unsafe void get_sp (int i) {
2438 addr [i] = new IntPtr (&i);
2441 /* Test that the arguments to the throw trampoline are correctly popped off the stack */
2442 public static int test_0_throw_unwind () {
2443 addr = new IntPtr [1000];
2445 for (int j = 0; j < 1000; j++) {
2448 throw new Exception ();
2453 return (addr [0].ToInt64 () - addr [100].ToInt64 () < 100) ? 0 : 1;
2456 public static int test_0_regress_73242 () {
2457 int [] arr = new int [10];
2458 for (int i = 0; i < 10; ++i)
2461 throw new Exception ();
2468 public static int test_0_nullref () {
2472 } catch (NullReferenceException e) {
2478 public int amethod () {
2482 public static int test_0_nonvirt_nullref_at_clause_start () {
2483 ExceptionTests t = null;
2486 } catch (NullReferenceException) {
2493 public static int throw_only () {
2494 throw new Exception ();
2497 [MethodImpl(MethodImplOptions.NoInlining)]
2498 public static int throw_only2 () {
2499 return throw_only ();
2502 public static int test_0_inline_throw_only () {
2504 return throw_only2 ();
2506 catch (Exception ex) {
2511 public static string GetText (string s) {
2515 public static int throw_only_gettext () {
2516 throw new Exception (GetText ("FOO"));
2519 public static int test_0_inline_throw_only_gettext () {
2522 o = throw_only_gettext ();
2524 catch (Exception ex) {
2528 return o != null ? 0 : 1;
2532 public static int test_0_throw_to_branch_opt_outer_clause () {
2537 string [] files = new string[1];
2539 string s = files[2];
2546 return (i == 1) ? 0 : 1;
2550 public static int test_0_try_inside_finally_cmov_opt () {
2551 bool Reconect = false;
2553 object o = new object ();
2557 catch (Exception ExCon) {
2563 catch (Exception Last) {
2567 if (Reconect == true) {
2570 catch (Exception ex) {
2578 public static int test_0_inline_throw () {
2587 // for llvm, the end bblock is unreachable
2588 public static int inline_throw1 (int i) {
2590 throw new Exception ();
2592 return inline_throw2 (i);
2595 public static int inline_throw2 (int i) {
2596 throw new Exception ();
2600 public static int test_0_lmf_filter () {
2602 // The invoke calls a runtime-invoke wrapper which has a filter clause
2604 typeof (ExceptionTests).GetMethod ("lmf_filter").Invoke (null, new object [] { });
2606 typeof (Tests).GetMethod ("lmf_filter").Invoke (null, new object [] { });
2608 } catch (TargetInvocationException) {
2613 public static void lmf_filter () {
2618 throw new NotImplementedException ();
2622 public static void Connect () {
2624 throw new Exception();
2627 public static void Stop () {
2635 private static void do_raise () {
2636 throw new System.Exception ();
2639 private static int int_func (int i) {
2644 public static int test_8_local_deadce_causes () {
2651 } catch (System.Exception) {
2657 public static int test_0_except_opt_two_clauses () {
2660 uint ui = (uint)size;
2663 uint v = ui * (uint)4;
2665 } catch (OverflowException e) {
2667 } catch (Exception) {
2676 public virtual long Method()
2678 throw new Exception();
2683 public static int test_100_long_vars_in_clauses_initlocals_opt () {
2684 Child c = new Child();
2694 public object AnObj;
2697 public static void DoSomething (ref object o) {
2700 public static int test_0_ldflda_null () {
2704 DoSomething (ref a.AnObj);
2705 } catch (NullReferenceException) {
2716 public static Foo* pFoo;
2719 [Category ("!INTERPRETER")]
2720 /* MS.NET doesn't seem to throw in this case */
2721 public unsafe static int test_0_ldflda_null_pointer () {
2722 int* pi = &Foo.pFoo->i;
2727 static int test_0_try_clause_in_finally_clause_regalloc () {
2728 // Fill up registers with values
2729 object a = new object ();
2730 object[] arr1 = new object [1];
2731 object[] arr2 = new object [1];
2732 object[] arr3 = new object [1];
2733 object[] arr4 = new object [1];
2734 object[] arr5 = new object [1];
2736 for (int i = 0; i < 10; ++i)
2738 for (int i = 0; i < 10; ++i)
2740 for (int i = 0; i < 10; ++i)
2742 for (int i = 0; i < 10; ++i)
2744 for (int i = 0; i < 10; ++i)
2749 try_clause_in_finally_clause_regalloc_inner (out res);
2750 } catch (Exception) {
2755 public static object Throw () {
2756 for (int i = 0; i < 10; ++i)
2758 throw new Exception ();
2761 static void try_clause_in_finally_clause_regalloc_inner (out int res) {
2767 } catch (Exception) {
2768 /* Make sure this doesn't branch to the finally */
2769 throw new DivideByZeroException ();
2772 /* Make sure o is register allocated */
2785 } catch (DivideByZeroException) {
2790 public static bool t_1835_inner () {
2792 if (a) throw new Exception();
2796 [MethodImpl(MethodImplOptions.NoInlining)]
2797 public static bool t_1835_inner_2 () {
2798 bool b = t_1835_inner ();
2802 public static int test_0_inline_retval_throw_in_branch_1835 () {
2811 static bool finally_called = false;
2813 static void regress_30472 (int a, int b) {
2818 finally_called = true;
2823 public static int test_0_regress_30472 () {
2824 finally_called = false;
2826 regress_30472 (Int32.MaxValue - 1, 2);
2827 } catch (Exception ex) {
2829 return finally_called ? 0 : 1;
2832 static int array_len_1 = 1;
2834 public static int test_0_bounds_check_negative_constant () {
2836 byte[] arr = new byte [array_len_1];
2842 byte[] arr = new byte [array_len_1];
2850 public static int test_0_string_bounds_check_negative_constant () {
2862 class ExceptionTests : Tests