[aot] fix linker invocation for llvm mode on linux
[mono.git] / mono / mini / exceptions.cs
index 6affc7d25bfdfe8cd940081a9ce9d83e1e9d5fc8..98c6046e61a5cdea5dab273ee1b289d63c26a7b5 100644 (file)
@@ -24,11 +24,18 @@ using System.Runtime.CompilerServices;
  * 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 ();
@@ -1455,6 +1462,7 @@ class Tests {
                return 0;
        }
        
+       [Category ("NaClDisable")]
        public static int test_0_div_zero () {
                int d = 1;
                int q = 0;
@@ -1508,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;
        }
@@ -1560,6 +1633,7 @@ class Tests {
                return 0;
        }
 
+       [Category ("NaClDisable")]
        public static int test_0_long_div_zero () {
                long d = 1;
                long q = 0;
@@ -2232,24 +2306,24 @@ class Tests {
                return 2;
        }
 
-       /* MarshalByRefObject prevents the methods from being inlined */
-       class ThrowClass : MarshalByRefObject {
-               public static void rethrow1 () {
-                       throw new Exception ();
-               }
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void rethrow1 () {
+               throw new Exception ();
+       }
 
-               public static void rethrow2 () {
-                       rethrow1 ();
-                       /* This disables tailcall opts */
-                       Console.WriteLine ();
-               }
+       [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
@@ -2309,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];
@@ -2344,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 ();
@@ -2356,6 +2422,7 @@ class Tests {
                }
                return (addr [0].ToInt64 () - addr [100].ToInt64 () < 100) ? 0 : 1;
        }
+       */
 
        static unsafe void get_sp (int i) {
                addr [i] = new IntPtr (&i);
@@ -2403,7 +2470,7 @@ class Tests {
        }
 
        public static int test_0_nonvirt_nullref_at_clause_start () {
-               Tests t = null;
+               ExceptionTests t = null;
                try {
                        t.amethod ();
                } catch (NullReferenceException) {
@@ -2523,7 +2590,11 @@ class Tests {
        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;
@@ -2641,5 +2712,143 @@ class Tests {
 
                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