Handle fallthru to out of line blocks.
[mono.git] / mono / mini / exceptions.cs
index 0cd1fde97b01c16d88032b159631a30ccdcd3c5f..6affc7d25bfdfe8cd940081a9ce9d83e1e9d5fc8 100644 (file)
@@ -1486,7 +1486,7 @@ class Tests {
                        val = d / q;
                } catch (DivideByZeroException) {
                        /* wrong exception */
-               } catch (ArithmeticException) {
+               } catch (OverflowException) {
                        failed = false;
                }
                if (failed)
@@ -1499,7 +1499,7 @@ class Tests {
                        val = d % q;
                } catch (DivideByZeroException) {
                        /* wrong exception */
-               } catch (ArithmeticException) {
+               } catch (OverflowException) {
                        failed = false;
                }
                if (failed)
@@ -2240,6 +2240,8 @@ class Tests {
 
                public static void rethrow2 () {
                        rethrow1 ();
+                       /* This disables tailcall opts */
+                       Console.WriteLine ();
                }
        }
 
@@ -2355,6 +2357,25 @@ 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];
                for (int i = 0; i < 10; ++i)
@@ -2447,5 +2468,178 @@ 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
+                       typeof (Tests).GetMethod ("lmf_filter").Invoke (null, new object [] { });
+               } 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;
+       }
 }