X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fexceptions.cs;h=98c6046e61a5cdea5dab273ee1b289d63c26a7b5;hb=dbaca79c4797350ac59026278561e325a86b7a40;hp=839aa4c81369bc17ced6df4af85b7e3008e9daab;hpb=89d0ba3968d36576553e0f483b0c69465f94e8ae;p=mono.git diff --git a/mono/mini/exceptions.cs b/mono/mini/exceptions.cs index 839aa4c8136..98c6046e61a 100644 --- a/mono/mini/exceptions.cs +++ b/mono/mini/exceptions.cs @@ -1,5 +1,6 @@ using System; using System.Reflection; +using System.Runtime.CompilerServices; /* * Regression tests for the mono JIT. @@ -23,11 +24,18 @@ using System.Reflection; * the IL code looks. */ -class Tests { +#if __MOBILE__ +class ExceptionTests +#else +class Tests +#endif +{ - public static int Main () { - return TestDriver.RunTests (typeof (Tests)); +#if !__MOBILE__ + public static int Main (string[] args) { + return TestDriver.RunTests (typeof (Tests), args); } +#endif public static int test_0_catch () { Exception x = new Exception (); @@ -1454,6 +1462,7 @@ class Tests { return 0; } + [Category ("NaClDisable")] public static int test_0_div_zero () { int d = 1; int q = 0; @@ -1485,7 +1494,7 @@ class Tests { val = d / q; } catch (DivideByZeroException) { /* wrong exception */ - } catch (ArithmeticException) { + } catch (OverflowException) { failed = false; } if (failed) @@ -1498,7 +1507,7 @@ class Tests { val = d % q; } catch (DivideByZeroException) { /* wrong exception */ - } catch (ArithmeticException) { + } catch (OverflowException) { failed = false; } if (failed) @@ -1507,6 +1516,71 @@ class Tests { return 0; } + [MethodImplAttribute (MethodImplOptions.NoInlining)] + static void dummy () { + } + + [MethodImplAttribute (MethodImplOptions.NoInlining)] + static int div_zero_llvm_inner (int i) { + try { + // This call make use avoid the 'handler without invoke' restriction in the llvm backend + dummy (); + return 5 / i; + } catch (Exception ex) { + return 0; + } + } + + [MethodImplAttribute (MethodImplOptions.NoInlining)] + static long div_zero_llvm_inner_long (long l) { + try { + dummy (); + return (long)5 / l; + } catch (Exception ex) { + return 0; + } + } + + public static int test_0_div_zero_llvm () { + long r = div_zero_llvm_inner (0); + if (r != 0) + return 1; + r = div_zero_llvm_inner_long (0); + if (r != 0) + return 2; + return 0; + } + + [MethodImplAttribute (MethodImplOptions.NoInlining)] + static int div_overflow_llvm_inner (int i) { + try { + dummy (); + return Int32.MinValue / i; + } catch (Exception ex) { + return 0; + } + } + + [MethodImplAttribute (MethodImplOptions.NoInlining)] + static long div_overflow_llvm_inner_long (long l) { + try { + dummy (); + return Int64.MinValue / l; + } catch (Exception ex) { + return 0; + } + } + + public static int test_0_div_overflow_llvm () { + long r = div_overflow_llvm_inner (-1); + if (r != 0) + return 1; + r = div_overflow_llvm_inner_long ((long)-1); + if (r != 0) + return 2; + return 0; + } + public static int return_55 () { return 55; } @@ -1559,6 +1633,7 @@ class Tests { return 0; } + [Category ("NaClDisable")] public static int test_0_long_div_zero () { long d = 1; long q = 0; @@ -1821,241 +1896,326 @@ class Tests { return 2; } - public static int test_0_ovf () { - int ocount = 0; + public static int test_0_ovf1 () { + int exception = 0; checked { - - ocount = 0; try { ulong a = UInt64.MaxValue - 1; ulong t = a++; } catch { - ocount++; + exception = 1; } - if (ocount != 0) - return 1; + } + return exception; + } - ocount = 0; + public static int test_1_ovf2 () { + int exception = 0; + + checked { try { ulong a = UInt64.MaxValue; ulong t = a++; } catch { - ocount++; + exception = 1; } - if (ocount != 1) - return 2; + } + return exception; + } + + public static int test_0_ovf3 () { + int exception = 0; - ocount = 0; + long a = Int64.MaxValue - 1; + checked { try { - long a = Int64.MaxValue - 1; long t = a++; } catch { - ocount++; + exception = 1; } - if (ocount != 0) - return 3; + } + return exception; + } + public static int test_1_ovf4 () { + int exception = 0; + + long a = Int64.MaxValue; + checked { try { - long a = Int64.MaxValue; long t = a++; } catch { - ocount++; + exception = 1; } - if (ocount != 1) - return 4; + } + return exception; + } + + public static int test_0_ovf5 () { + int exception = 0; - ocount = 0; + ulong a = UInt64.MaxValue - 1; + checked { try { - ulong a = UInt64.MaxValue - 1; ulong t = a++; } catch { - ocount++; + exception = 1; } - if (ocount != 0) - return 5; + } + return exception; + } + public static int test_1_ovf6 () { + int exception = 0; + + ulong a = UInt64.MaxValue; + checked { try { - ulong a = UInt64.MaxValue; ulong t = a++; } catch { - ocount++; + exception = 1; } - if (ocount != 1) - return 6; + } + return exception; + } + + public static int test_0_ovf7 () { + int exception = 0; - ocount = 0; + long a = Int64.MinValue + 1; + checked { try { - long a = Int64.MinValue + 1; long t = a--; } catch { - ocount++; + exception = 1; } - if (ocount != 0) - return 7; + } + return 0; + } - ocount = 0; + public static int test_1_ovf8 () { + int exception = 0; + + long a = Int64.MinValue; + checked { try { - long a = Int64.MinValue; long t = a--; } catch { - ocount++; + exception = 1; } - if (ocount != 1) - return 8; + } + return exception; + } + + public static int test_0_ovf9 () { + int exception = 0; - ocount = 0; + ulong a = UInt64.MinValue + 1; + checked { try { - ulong a = UInt64.MinValue + 1; ulong t = a--; } catch { - ocount++; + exception = 1; } - if (ocount != 0) - return 9; + } + return exception; + } - ocount = 0; + public static int test_1_ovf10 () { + int exception = 0; + + ulong a = UInt64.MinValue; + checked { try { - ulong a = UInt64.MinValue; ulong t = a--; } catch { - ocount++; + exception = 1; } - if (ocount != 1) - return 10; + } + return exception; + } + + public static int test_0_ovf11 () { + int exception = 0; - ocount = 0; + int a = Int32.MinValue + 1; + checked { try { - int a = Int32.MinValue + 1; int t = a--; } catch { - ocount++; + exception = 1; } - if (ocount != 0) - return 11; + } + return exception; + } - ocount = 0; + public static int test_1_ovf12 () { + int exception = 0; + + int a = Int32.MinValue; + checked { try { - int a = Int32.MinValue; int t = a--; } catch { - ocount++; + exception = 1; } - if (ocount != 1) - return 12; + } + return exception; + } + + public static int test_0_ovf13 () { + int exception = 0; - ocount = 0; + uint a = 1; + checked { try { - uint a = 1; uint t = a--; } catch { - ocount++; + exception = 1; } - if (ocount != 0) - return 13; + } + return exception; + } - ocount = 0; + public static int test_1_ovf14 () { + int exception = 0; + + uint a = 0; + checked { try { - uint a = 0; uint t = a--; } catch { - ocount++; + exception = 1; } - if (ocount != 1) - return 14; + } + return exception; + } + + public static int test_0_ovf15 () { + int exception = 0; - ocount = 0; + sbyte a = 126; + checked { try { - sbyte a = 126; sbyte t = a++; } catch { - ocount++; + exception = 1; } - if (ocount != 0) - return 15; + } + return exception; + } + + public static int test_1_ovf16 () { + int exception = 0; - ocount = 0; + sbyte a = 127; + checked { try { - sbyte a = 127; sbyte t = a++; } catch { - ocount++; + exception = 1; } - if (ocount != 1) - return 16; + } + return exception; + } + + public static int test_0_ovf17 () { + int exception = 0; - ocount = 0; + checked { try { } catch { - ocount++; + exception = 1; } - if (ocount != 0) - return 17; + } + return exception; + } + + public static int test_0_ovf18 () { + int exception = 0; - ocount = 0; + int a = 1 << 29; + checked { try { - int a = 1 << 29; int t = a*2; } catch { - ocount++; + exception = 1; } - if (ocount != 0) - return 18; + } + return exception; + } - ocount = 0; + public static int test_1_ovf19 () { + int exception = 0; + + int a = 1 << 30; + checked { try { - int a = 1 << 30; int t = a*2; } catch { - ocount++; + exception = 1; } - if (ocount != 1) - return 19; + } + return exception; + } + + public static int test_0_ovf20 () { + int exception = 0; - ocount = 0; + checked { try { ulong a = 0xffffffffff; ulong t = a*0x0ffffff; } catch { - ocount++; + exception = 1; } - if (ocount != 0) - return 20; + } + return exception; + } - ocount = 0; + public static int test_1_ovf21 () { + int exception = 0; + + ulong a = 0xffffffffff; + checked { try { - ulong a = 0xffffffffff; ulong t = a*0x0fffffff; } catch { - ocount++; + exception = 1; } - if (ocount != 1) - return 21; + } + return exception; + } - ocount = 0; + public static int test_1_ovf22 () { + int exception = 0; + + long a = Int64.MinValue; + long b = 10; + checked { try { - long a = Int64.MinValue; - long b = 10; long v = a * b; } catch { - ocount ++; + exception = 1; } - if (ocount != 1) - return 22; + } + return exception; + } + + public static int test_1_ovf23 () { + int exception = 0; - ocount = 0; + long a = 10; + long b = Int64.MinValue; + checked { try { - long a = 10; - long b = Int64.MinValue; long v = a * b; } catch { - ocount ++; + exception = 1; } - if (ocount != 1) - return 23; } - - return 0; + return exception; } class Broken { @@ -2122,22 +2282,48 @@ class Tests { return i; } - /* MarshalByRefObject prevents the methods from being inlined */ - class ThrowClass : MarshalByRefObject { - public static void rethrow1 () { - throw new Exception (); + public static void rethrow () { + try { + throw new ApplicationException(); + } catch (ApplicationException) { + try { + throw new OverflowException(); + } catch (Exception) { + throw; + } } + } - public static void rethrow2 () { - rethrow1 (); + // Test that a rethrow rethrows the correct exception + public static int test_0_rethrow_nested () { + try { + rethrow (); + } catch (OverflowException) { + return 0; + } catch (Exception) { + return 1; } + return 2; + } + + [MethodImplAttribute (MethodImplOptions.NoInlining)] + public static void rethrow1 () { + throw new Exception (); } + [MethodImplAttribute (MethodImplOptions.NoInlining)] + public static void rethrow2 () { + rethrow1 (); + /* This disables tailcall opts */ + Console.WriteLine (); + } + + [Category ("!BITCODE")] public static int test_0_rethrow_stacktrace () { // Check that rethrowing an exception preserves the original stack trace try { try { - ThrowClass.rethrow2 (); + rethrow2 (); } catch (Exception ex) { // Check that each catch clause has its own exception variable @@ -2197,16 +2383,6 @@ class Tests { public static int test_0_array_size () { bool failed; - try { - failed = true; - int[] mem1 = new int [Int32.MaxValue]; - } - catch (OutOfMemoryException e) { - failed = false; - } - if (failed) - return 1; - try { failed = true; int[,] mem2 = new int [Int32.MaxValue, Int32.MaxValue]; @@ -2232,6 +2408,8 @@ class Tests { } /* Test that arguments are correctly popped off the stack during unwinding */ + /* FIXME: Fails on x86 when llvm is enabled (#5432) */ + /* public static int test_0_stack_unwind () { addr = new IntPtr [1000]; S s = new S (); @@ -2244,6 +2422,26 @@ class Tests { } return (addr [0].ToInt64 () - addr [100].ToInt64 () < 100) ? 0 : 1; } + */ + + static unsafe void get_sp (int i) { + addr [i] = new IntPtr (&i); + } + + /* Test that the arguments to the throw trampoline are correctly popped off the stack */ + public static int test_0_throw_unwind () { + addr = new IntPtr [1000]; + S s = new S (); + for (int j = 0; j < 1000; j++) { + try { + get_sp (j); + throw new Exception (); + } + catch (Exception) { + } + } + return (addr [0].ToInt64 () - addr [100].ToInt64 () < 100) ? 0 : 1; + } public static int test_0_regress_73242 () { int [] arr = new int [10]; @@ -2267,6 +2465,59 @@ class Tests { return 1; } + public int amethod () { + return 1; + } + + public static int test_0_nonvirt_nullref_at_clause_start () { + ExceptionTests t = null; + try { + t.amethod (); + } catch (NullReferenceException) { + return 0; + } + + return 1; + } + + public static int throw_only () { + throw new Exception (); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static int throw_only2 () { + return throw_only (); + } + + public static int test_0_inline_throw_only () { + try { + return throw_only2 (); + } + catch (Exception ex) { + return 0; + } + } + + public static string GetText (string s) { + return s; + } + + public static int throw_only_gettext () { + throw new Exception (GetText ("FOO")); + } + + public static int test_0_inline_throw_only_gettext () { + object o = null; + try { + o = throw_only_gettext (); + } + catch (Exception ex) { + return 0; + } + + return o != null ? 0 : 1; + } + // bug #78633 public static int test_0_throw_to_branch_opt_outer_clause () { int i = 0; @@ -2284,5 +2535,320 @@ class Tests { return (i == 1) ? 0 : 1; } + + // bug #485721 + public static int test_0_try_inside_finally_cmov_opt () { + bool Reconect = false; + + object o = new object (); + + try { + } + catch (Exception ExCon) { + if (o != null) + Reconect = true; + + try { + } + catch (Exception Last) { + } + } + finally { + if (Reconect == true) { + try { + } + catch (Exception ex) { + } + } + } + + return 0; + } + + public static int test_0_inline_throw () { + try { + inline_throw1 (5); + return 1; + } catch { + return 0; + } + } + + // for llvm, the end bblock is unreachable + public static int inline_throw1 (int i) { + if (i == 0) + throw new Exception (); + else + return inline_throw2 (i); + } + + public static int inline_throw2 (int i) { + throw new Exception (); + } + + // bug #539550 + public static int test_0_lmf_filter () { + try { + // The invoke calls a runtime-invoke wrapper which has a filter clause +#if __MOBILE__ + typeof (ExceptionTests).GetMethod ("lmf_filter").Invoke (null, new object [] { }); +#else + typeof (Tests).GetMethod ("lmf_filter").Invoke (null, new object [] { }); +#endif + } catch (TargetInvocationException) { + } + return 0; + } + + public static void lmf_filter () { + try { + Connect (); + } + catch { + throw new NotImplementedException (); + } + } + + public static void Connect () { + Stop (); + throw new Exception(); + } + + public static void Stop () { + try { + lock (null) {} + } + catch { + } + } + + private static void do_raise () { + throw new System.Exception (); + } + + private static int int_func (int i) { + return i; + } + + // #559876 + public static int test_8_local_deadce_causes () { + int myb = 4; + + try { + myb = int_func (8); + do_raise(); + myb = int_func (2); + } catch (System.Exception) { + return myb; + } + return 0; + } + + public static int test_0_except_opt_two_clauses () { + int size; + size = -1; + uint ui = (uint)size; + try { + checked { + uint v = ui * (uint)4; + } + } catch (OverflowException e) { + return 0; + } catch (Exception) { + return 1; + } + + return 2; + } + + class Child + { + public virtual long Method() + { + throw new Exception(); + } + } + + /* #612206 */ + public static int test_100_long_vars_in_clauses_initlocals_opt () { + Child c = new Child(); + long value = 100; + try { + value = c.Method(); + } + catch {} + return (int)value; + } + + class A { + public object AnObj; + } + + public static void DoSomething (ref object o) { + } + + public static int test_0_ldflda_null () { + A a = null; + + try { + DoSomething (ref a.AnObj); + } catch (NullReferenceException) { + return 0; + } + + return 1; + } + + unsafe struct Foo + { + public int i; + + public static Foo* pFoo; + } + + /* MS.NET doesn't seem to throw in this case */ + public unsafe static int test_0_ldflda_null_pointer () { + int* pi = &Foo.pFoo->i; + + return 0; + } + + static int test_0_try_clause_in_finally_clause_regalloc () { + // Fill up registers with values + object a = new object (); + object[] arr1 = new object [1]; + object[] arr2 = new object [1]; + object[] arr3 = new object [1]; + object[] arr4 = new object [1]; + object[] arr5 = new object [1]; + + for (int i = 0; i < 10; ++i) + arr1 [0] = a; + for (int i = 0; i < 10; ++i) + arr2 [0] = a; + for (int i = 0; i < 10; ++i) + arr3 [0] = a; + for (int i = 0; i < 10; ++i) + arr4 [0] = a; + for (int i = 0; i < 10; ++i) + arr5 [0] = a; + + int res = 1; + try { + try_clause_in_finally_clause_regalloc_inner (out res); + } catch (Exception) { + } + return res; + } + + public static object Throw () { + for (int i = 0; i < 10; ++i) + ; + throw new Exception (); + } + + static void try_clause_in_finally_clause_regalloc_inner (out int res) { + object o = null; + + res = 1; + try { + o = Throw (); + } catch (Exception) { + /* Make sure this doesn't branch to the finally */ + throw new DivideByZeroException (); + } finally { + try { + /* Make sure o is register allocated */ + if (o == null) + res = 0; + else + res = 1; + if (o == null) + res = 0; + else + res = 1; + if (o == null) + res = 0; + else + res = 1; + } catch (DivideByZeroException) { + } + } + } + + public static bool t_1835_inner () { + bool a = true; + if (a) throw new Exception(); + return true; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static bool t_1835_inner_2 () { + bool b = t_1835_inner (); + return b; + } + + public static int test_0_inline_retval_throw_in_branch_1835 () { + try { + t_1835_inner_2 (); + } catch { + return 0; + } + return 1; + } + + static bool finally_called = false; + + static void regress_30472 (int a, int b) { + checked { + try { + int sum = a + b; + } finally { + finally_called = true; + } + } + } + + public static int test_0_regress_30472 () { + finally_called = false; + try { + regress_30472 (Int32.MaxValue - 1, 2); + } catch (Exception ex) { + } + return finally_called ? 0 : 1; + } + + static int array_len_1 = 1; + + public static int test_0_bounds_check_negative_constant () { + try { + byte[] arr = new byte [array_len_1]; + byte b = arr [-1]; + return 1; + } catch { + } + try { + byte[] arr = new byte [array_len_1]; + arr [-1] = 1; + return 2; + } catch { + } + return 0; + } + + public static int test_0_string_bounds_check_negative_constant () { + try { + string s = "A"; + char c = s [-1]; + return 1; + } catch { + } + return 0; + } } +#if !__MOBILE__ +class ExceptionTests : Tests +{ +} +#endif