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 (string[] args) {
30 return TestDriver.RunTests (typeof (Tests), args);
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 [Category ("NaClDisable")]
1459 public static int test_0_div_zero () {
1468 } catch (DivideByZeroException) {
1477 } catch (DivideByZeroException) {
1488 } catch (DivideByZeroException) {
1489 /* wrong exception */
1490 } catch (OverflowException) {
1501 } catch (DivideByZeroException) {
1502 /* wrong exception */
1503 } catch (OverflowException) {
1512 public static int return_55 () {
1516 public static int test_0_cfold_div_zero () {
1517 // Test that constant folding doesn't cause division by zero exceptions
1518 if (return_55 () != return_55 ()) {
1537 public static int test_0_udiv_zero () {
1546 } catch (DivideByZeroException) {
1555 } catch (DivideByZeroException) {
1564 [Category ("NaClDisable")]
1565 public static int test_0_long_div_zero () {
1574 } catch (DivideByZeroException) {
1583 } catch (DivideByZeroException) {
1594 } catch (DivideByZeroException) {
1595 /* wrong exception */
1596 } catch (ArithmeticException) {
1607 } catch (DivideByZeroException) {
1608 /* wrong exception */
1609 } catch (ArithmeticException) {
1618 public static int test_0_ulong_div_zero () {
1627 } catch (DivideByZeroException) {
1636 } catch (DivideByZeroException) {
1645 public static int test_0_float_div_zero () {
1654 } catch (DivideByZeroException) {
1663 } catch (DivideByZeroException) {
1672 public static int test_0_invalid_unbox () {
1675 object o = "Some string";
1679 // Illegal conversion; o contains a string not an int
1681 } catch (Exception e) {
1689 // Test that double[] can't be cast to double (bug #46027)
1690 public static int test_0_invalid_unbox_arrays () {
1691 double[] d1 = { 1.0 };
1692 double[][] d2 = { d1 };
1696 foreach (double d in a) {
1700 catch (InvalidCastException e) {
1705 /* bug# 42190, at least mcs generates a leave for the return that
1706 * jumps out of multiple exception clauses: we used to execute just
1707 * one enclosing finally block.
1709 public static int finally_level;
1710 static void do_something () {
1723 public static int test_2_multiple_finally_clauses () {
1726 if (finally_level == 1)
1731 public static int test_3_checked_cast_un () {
1732 ulong i = 0x8000000034000000;
1736 checked { j = (long)i; }
1737 } catch (OverflowException) {
1746 public static int test_4_checked_cast () {
1750 unchecked { i = (long)0x8000000034000000;};
1752 checked { j = (ulong)i; }
1753 } catch (OverflowException) {
1762 static readonly int[] mul_dim_results = new int[] {
1763 0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8,
1764 1, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8,
1768 5, 0, 5, 1, 5, 2, 5, 3, 5, 4, 5, 5, 5, 6, 5, 7, 5, 8,
1769 6, 0, 6, 1, 6, 2, 6, 3, 6, 4, 6, 5, 6, 6, 6, 7, 6, 8,
1770 7, 0, 7, 1, 7, 2, 7, 3, 7, 4, 7, 5, 7, 6, 7, 7, 7, 8,
1773 public static int test_0_multi_dim_array_access () {
1774 int [,] a = System.Array.CreateInstance (typeof (int),
1775 new int [] {3,6}, new int [] {2,2 }) as int[,];
1778 for (x = 0; x < 8; ++x) {
1779 for (y = 0; y < 9; ++y) {
1780 bool got_ex = false;
1787 if (result_idx >= mul_dim_results.Length)
1789 if (mul_dim_results [result_idx] != x || mul_dim_results [result_idx + 1] != y) {
1790 return result_idx + 1;
1796 if (result_idx == mul_dim_results.Length)
1801 static void helper_out_obj (out object o) {
1802 o = (object)"buddy";
1805 static void helper_out_string (out string o) {
1809 public static int test_2_array_mismatch () {
1810 string[] a = { "hello", "world" };
1812 bool passed = false;
1815 helper_out_obj (out b [1]);
1816 } catch (ArrayTypeMismatchException) {
1821 helper_out_string (out a [1]);
1822 if (a [1] != "buddy")
1827 public static int test_0_ovf1 () {
1832 ulong a = UInt64.MaxValue - 1;
1841 public static int test_1_ovf2 () {
1846 ulong a = UInt64.MaxValue;
1855 public static int test_0_ovf3 () {
1858 long a = Int64.MaxValue - 1;
1869 public static int test_1_ovf4 () {
1872 long a = Int64.MaxValue;
1883 public static int test_0_ovf5 () {
1886 ulong a = UInt64.MaxValue - 1;
1897 public static int test_1_ovf6 () {
1900 ulong a = UInt64.MaxValue;
1911 public static int test_0_ovf7 () {
1914 long a = Int64.MinValue + 1;
1925 public static int test_1_ovf8 () {
1928 long a = Int64.MinValue;
1939 public static int test_0_ovf9 () {
1942 ulong a = UInt64.MinValue + 1;
1953 public static int test_1_ovf10 () {
1956 ulong a = UInt64.MinValue;
1967 public static int test_0_ovf11 () {
1970 int a = Int32.MinValue + 1;
1981 public static int test_1_ovf12 () {
1984 int a = Int32.MinValue;
1995 public static int test_0_ovf13 () {
2009 public static int test_1_ovf14 () {
2023 public static int test_0_ovf15 () {
2037 public static int test_1_ovf16 () {
2051 public static int test_0_ovf17 () {
2063 public static int test_0_ovf18 () {
2077 public static int test_1_ovf19 () {
2091 public static int test_0_ovf20 () {
2096 ulong a = 0xffffffffff;
2097 ulong t = a*0x0ffffff;
2105 public static int test_1_ovf21 () {
2108 ulong a = 0xffffffffff;
2111 ulong t = a*0x0fffffff;
2119 public static int test_1_ovf22 () {
2122 long a = Int64.MinValue;
2134 public static int test_1_ovf23 () {
2138 long b = Int64.MinValue;
2150 public static int i;
2153 throw new Exception ("Ugh!");
2156 public static int DoSomething () {
2161 public static int test_0_exception_in_cctor () {
2163 Broken.DoSomething ();
2165 catch (TypeInitializationException) {
2166 // This will only happen once even if --regression is used
2171 public static int test_5_regalloc () {
2175 for (i = 0; i < 10; ++i) {
2177 throw new Exception ();
2185 // Check that variables written in catch clauses are volatile
2188 throw new Exception ();
2199 throw new Exception ();
2213 public static void rethrow () {
2215 throw new ApplicationException();
2216 } catch (ApplicationException) {
2218 throw new OverflowException();
2219 } catch (Exception) {
2225 // Test that a rethrow rethrows the correct exception
2226 public static int test_0_rethrow_nested () {
2229 } catch (OverflowException) {
2231 } catch (Exception) {
2237 /* MarshalByRefObject prevents the methods from being inlined */
2238 class ThrowClass : MarshalByRefObject {
2239 public static void rethrow1 () {
2240 throw new Exception ();
2243 public static void rethrow2 () {
2245 /* This disables tailcall opts */
2246 Console.WriteLine ();
2250 public static int test_0_rethrow_stacktrace () {
2251 // Check that rethrowing an exception preserves the original stack trace
2254 ThrowClass.rethrow2 ();
2256 catch (Exception ex) {
2257 // Check that each catch clause has its own exception variable
2258 // If not, the throw below will overwrite the exception used
2261 throw new DivideByZeroException ();
2263 catch (Exception foo) {
2269 catch (Exception ex) {
2270 if (ex.StackTrace.IndexOf ("rethrow2") != -1)
2278 class Face : IFace {}
2280 public static int test_1_array_mismatch_2 () {
2282 object [] o = new Face [1];
2285 } catch (ArrayTypeMismatchException) {
2290 public static int test_1_array_mismatch_3 () {
2292 object [] o = new IFace [1];
2295 } catch (ArrayTypeMismatchException) {
2300 public static int test_1_array_mismatch_4 () {
2302 object [][] o = new Face [5] [];
2303 o [0] = new object [5];
2306 } catch (ArrayTypeMismatchException) {
2311 public static int test_0_array_size () {
2316 int[] mem1 = new int [Int32.MaxValue];
2318 catch (OutOfMemoryException e) {
2326 int[,] mem2 = new int [Int32.MaxValue, Int32.MaxValue];
2328 catch (OutOfMemoryException e) {
2338 int i, j, k, l, m, n;
2341 static IntPtr[] addr;
2343 static unsafe void throw_func (int i, S s) {
2344 addr [i] = new IntPtr (&i);
2345 throw new Exception ();
2348 /* Test that arguments are correctly popped off the stack during unwinding */
2349 /* FIXME: Fails on x86 when llvm is enabled (#5432) */
2351 public static int test_0_stack_unwind () {
2352 addr = new IntPtr [1000];
2354 for (int j = 0; j < 1000; j++) {
2361 return (addr [0].ToInt64 () - addr [100].ToInt64 () < 100) ? 0 : 1;
2365 static unsafe void get_sp (int i) {
2366 addr [i] = new IntPtr (&i);
2369 /* Test that the arguments to the throw trampoline are correctly popped off the stack */
2370 public static int test_0_throw_unwind () {
2371 addr = new IntPtr [1000];
2373 for (int j = 0; j < 1000; j++) {
2376 throw new Exception ();
2381 return (addr [0].ToInt64 () - addr [100].ToInt64 () < 100) ? 0 : 1;
2384 public static int test_0_regress_73242 () {
2385 int [] arr = new int [10];
2386 for (int i = 0; i < 10; ++i)
2389 throw new Exception ();
2396 public static int test_0_nullref () {
2400 } catch (NullReferenceException e) {
2406 public int amethod () {
2410 public static int test_0_nonvirt_nullref_at_clause_start () {
2414 } catch (NullReferenceException) {
2421 public static int throw_only () {
2422 throw new Exception ();
2425 [MethodImpl(MethodImplOptions.NoInlining)]
2426 public static int throw_only2 () {
2427 return throw_only ();
2430 public static int test_0_inline_throw_only () {
2432 return throw_only2 ();
2434 catch (Exception ex) {
2439 public static string GetText (string s) {
2443 public static int throw_only_gettext () {
2444 throw new Exception (GetText ("FOO"));
2447 public static int test_0_inline_throw_only_gettext () {
2450 o = throw_only_gettext ();
2452 catch (Exception ex) {
2456 return o != null ? 0 : 1;
2460 public static int test_0_throw_to_branch_opt_outer_clause () {
2465 string [] files = new string[1];
2467 string s = files[2];
2474 return (i == 1) ? 0 : 1;
2478 public static int test_0_try_inside_finally_cmov_opt () {
2479 bool Reconect = false;
2481 object o = new object ();
2485 catch (Exception ExCon) {
2491 catch (Exception Last) {
2495 if (Reconect == true) {
2498 catch (Exception ex) {
2506 public static int test_0_inline_throw () {
2515 // for llvm, the end bblock is unreachable
2516 public static int inline_throw1 (int i) {
2518 throw new Exception ();
2520 return inline_throw2 (i);
2523 public static int inline_throw2 (int i) {
2524 throw new Exception ();
2528 public static int test_0_lmf_filter () {
2530 // The invoke calls a runtime-invoke wrapper which has a filter clause
2531 typeof (Tests).GetMethod ("lmf_filter").Invoke (null, new object [] { });
2532 } catch (TargetInvocationException) {
2537 public static void lmf_filter () {
2542 throw new NotImplementedException ();
2546 public static void Connect () {
2548 throw new Exception();
2551 public static void Stop () {
2559 private static void do_raise () {
2560 throw new System.Exception ();
2563 private static int int_func (int i) {
2568 public static int test_8_local_deadce_causes () {
2575 } catch (System.Exception) {
2581 public static int test_0_except_opt_two_clauses () {
2584 uint ui = (uint)size;
2587 uint v = ui * (uint)4;
2589 } catch (OverflowException e) {
2591 } catch (Exception) {
2600 public virtual long Method()
2602 throw new Exception();
2607 public static int test_100_long_vars_in_clauses_initlocals_opt () {
2608 Child c = new Child();
2618 public object AnObj;
2621 public static void DoSomething (ref object o) {
2624 public static int test_0_ldflda_null () {
2628 DoSomething (ref a.AnObj);
2629 } catch (NullReferenceException) {
2640 public static Foo* pFoo;
2643 /* MS.NET doesn't seem to throw in this case */
2644 public unsafe static int test_0_ldflda_null_pointer () {
2645 int* pi = &Foo.pFoo->i;
2650 static int test_0_try_clause_in_finally_clause_regalloc () {
2651 // Fill up registers with values
2652 object a = new object ();
2653 object[] arr1 = new object [1];
2654 object[] arr2 = new object [1];
2655 object[] arr3 = new object [1];
2656 object[] arr4 = new object [1];
2657 object[] arr5 = new object [1];
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)
2667 for (int i = 0; i < 10; ++i)
2672 try_clause_in_finally_clause_regalloc_inner (out res);
2673 } catch (Exception) {
2678 public static object Throw () {
2679 for (int i = 0; i < 10; ++i)
2681 throw new Exception ();
2684 static void try_clause_in_finally_clause_regalloc_inner (out int res) {
2690 } catch (Exception) {
2691 /* Make sure this doesn't branch to the finally */
2692 throw new DivideByZeroException ();
2695 /* Make sure o is register allocated */
2708 } catch (DivideByZeroException) {
2713 public static bool t_1835_inner () {
2715 if (a) throw new Exception();
2719 [MethodImpl(MethodImplOptions.NoInlining)]
2720 public static bool t_1835_inner_2 () {
2721 bool b = t_1835_inner ();
2725 public static int test_0_inline_retval_throw_in_branch_1835 () {