Merge pull request #4418 from kumpera/fix_gclass_recording_on_failure
[mono.git] / mono / mini / arrays.cs
1 using System;
2 using System.Reflection;
3
4 /*
5  * Regression tests for the mono JIT.
6  *
7  * Each test needs to be of the form:
8  *
9  * static int test_<result>_<name> ();
10  *
11  * where <result> is an integer (the value that needs to be returned by
12  * the method to make it pass.
13  * <name> is a user-displayed name used to identify the test.
14  *
15  * The tests can be driven in two ways:
16  * *) running the program directly: Main() uses reflection to find and invoke
17  *      the test methods (this is useful mostly to check that the tests are correct)
18  * *) with the --regression switch of the jit (this is the preferred way since
19  *      all the tests will be run with optimizations on and off)
20  *
21  * The reflection logic could be moved to a .dll since we need at least another
22  * regression test file written in IL code to have better control on how
23  * the IL code looks.
24  */
25
26 #if __MOBILE__
27 class ArrayTests
28 #else
29 class Tests
30 #endif
31 {
32
33 #if !__MOBILE__
34         public static int Main (string[] args) {
35                 return TestDriver.RunTests (typeof (Tests), args);
36         }
37 #endif
38         
39         public static int test_10_create () {
40                 int[] a = new int [10];
41                 return a.Length;
42         }
43
44         public static int test_0_unset_value () {
45                 int[] a = new int [10];
46                 return a [5];
47         }
48
49         public static int test_3_set_value () {
50                 int[] a = new int [10];
51                 a [5] = 3;
52                 return a [5];
53         }
54
55         public static int test_0_char_array_1 () {
56                 int value = -30;
57                 char[] tmp = new char [20];
58                 char[] digitLowerTable = new char[16];
59                 tmp[0] = digitLowerTable[-(value % 10)];
60                 return 0;
61         }
62         
63         public static int test_0_char_array_2 () {
64                 int value = 5;
65                 char[] tmp = new char [20];
66                 char[] digitLowerTable = new char[16];
67                 tmp[0] = digitLowerTable[value % 10];
68                 return 0;
69         }
70
71         public static int test_0_char_array_3 () {
72                 int value = -1;
73                 char[] tmp = new char [20];
74                 char[] digitLowerTable = new char[16];
75                 tmp [0] = digitLowerTable[value & 15];          
76                 return 0;
77         }
78
79         public unsafe static int test_0_byte_array () {
80                 byte [] src = new byte [8];
81                 double ret;
82                 byte *dst = (byte *)&ret;
83                 int start = 0;
84
85                 dst[0] = src[4 + start];
86                 
87                 return 0;
88         }
89         
90         public static int test_0_set_after_shift () {
91                 int [] n = new int [1];
92                 int b = 16;
93                    
94                 n [0] = 100 + (1 << (16 - b));
95
96                 if (n [0] != 101)
97                         return 1;
98
99                 return 0;
100         }
101
102         /* Regression test for #30073 */
103         public static int test_0_newarr_emulation () {
104                 double d = 500;
105                 checked {
106                         double [] arr = new double [(int)d];
107                 }
108                 return 0;
109         }
110
111         class BitClass {
112                 private Int32[] m_array = new int [10];
113
114                 public void setBit (int bitIndex, bool value) {
115                         int index = bitIndex/32;
116                         int shift = bitIndex%32;
117
118                         Int32 theBit = 1 << shift;
119                         if (value)
120                                 m_array[index] |= theBit;
121                         else
122                                 m_array[index] &= ~theBit;
123                 }
124         
125                 public bool getBit (int bitIndex) {
126                         int index = bitIndex/32;
127                         int shift = bitIndex%32;
128
129                         Int32 theBit = m_array[index] & (1 << shift);
130                         return (theBit == 0) ? false : true;
131                 }
132         }
133         
134         public static int test_1_bit_index () {
135                 var t = new BitClass ();
136                 t.setBit (0, true);
137                 t.setBit (3, true);
138                 if (t.getBit (1))
139                         return 4;
140                 if (!t.getBit (0))
141                         return 5;
142                 if (!t.getBit (3))
143                         return 6;
144                 return 1;
145         }
146
147         class helper1 {
148
149                 int [] ma = new int [56];
150                 const int MBIG = int.MaxValue;
151
152                 public helper1 () {
153                         for (int k = 1; k < 5; k++) {
154                                 for (int i = 1; i < 56; i++) {
155                                         ma [i] -= ma [1 + (i + 30) % 55];
156                                         if (ma [i] < 0)
157                                                 ma [i] += MBIG;
158                                 }
159                         }
160                 }
161         }
162
163         public static int test_2_regalloc () {
164                 helper1 h = new helper1 ();
165                 return 2;
166         }
167         
168         public static int test_0_stelemref_1 () {
169                 object [] o = new object [1];
170                 o [0] = null;
171                 
172                 return 0;
173         }
174         
175         public static int test_0_stelemref_2 () {
176                 object [] o = new object [1];
177                 o [0] = 1;
178                 
179                 return 0;
180         }
181         
182         interface IFace {}
183         class Face : IFace {}
184         
185         public static int test_0_stelemref_3 () {
186                 object [] o = new IFace [1];
187                 o [0] = new Face ();
188                 
189                 return 0;
190         }
191         
192         public static int test_0_stelemref_4 () {
193                 object [][] o = new object [5] [];
194                 o [0] = new object [5];
195                 
196                 return 0;
197         }
198
199         struct FooStruct {
200                 public int i;
201
202                 public FooStruct (int i) {
203                         this.i = i;
204                 }
205         }
206
207         public static int test_0_arrays () {
208
209                 int sum;
210
211                 byte[] a1 = new byte [10];
212                 for (int i = 0; i < 10; ++i)
213                         a1 [i] = (byte)i;
214                 sum = 0;
215                 for (int i = 0; i < 10; ++i)
216                         sum += a1 [i];
217                 if (sum != 45)
218                         return 1;
219
220                 sbyte[] a2 = new sbyte [10];
221                 for (int i = 0; i < 10; ++i)
222                         a2 [i] = (sbyte)i;
223                 sum = 0;
224                 for (int i = 0; i < 10; ++i)
225                         sum += a2 [i];
226                 if (sum != 45)
227                         return 2;
228
229                 short[] a3 = new short [10];
230                 for (int i = 0; i < 10; ++i)
231                         a3 [i] = (short)i;
232                 sum = 0;
233                 for (int i = 0; i < 10; ++i)
234                         sum += a3 [i];
235                 if (sum != 45)
236                         return 3;
237
238                 ushort[] a4 = new ushort [10];
239                 for (int i = 0; i < 10; ++i)
240                         a4 [i] = (ushort)i;
241                 sum = 0;
242                 for (int i = 0; i < 10; ++i)
243                         sum += a4 [i];
244                 if (sum != 45)
245                         return 4;
246
247                 int[] a5 = new int [10];
248                 for (int i = 0; i < 10; ++i)
249                         a5 [i] = (int)i;
250                 sum = 0;
251                 for (int i = 0; i < 10; ++i)
252                         sum += a5 [i];
253                 if (sum != 45)
254                         return 5;
255
256                 uint[] a6 = new uint [10];
257                 for (int i = 0; i < 10; ++i)
258                         a6 [i] = (uint)i;
259                 sum = 0;
260                 for (int i = 0; i < 10; ++i)
261                         sum += (int)a6 [i];
262                 if (sum != 45)
263                         return 6;
264
265                 long[] a7 = new long [10];
266                 for (int i = 0; i < 10; ++i)
267                         a7 [i] = i;
268                 sum = 0;
269                 for (int i = 0; i < 10; ++i)
270                         sum += (int)a7 [i];
271                 if (sum != 45)
272                         return 7;
273
274                 ulong[] a8 = new ulong [10];
275                 for (int i = 0; i < 10; ++i)
276                         a8 [i] = (ulong)i;
277                 sum = 0;
278                 for (int i = 0; i < 10; ++i)
279                         sum += (int)a8 [i];
280                 if (sum != 45)
281                         return 8;
282
283                 float[] a9 = new float [10];
284                 for (int i = 0; i < 10; ++i)
285                         a9 [i] = (float)i;
286                 sum = 0;
287                 for (int i = 0; i < 10; ++i)
288                         sum += (int)a9 [i];
289                 if (sum != 45)
290                         return 9;
291
292                 double[] a10 = new double [10];
293                 for (int i = 0; i < 10; ++i)
294                         a10 [i] = i;
295                 sum = 0;
296                 for (int i = 0; i < 10; ++i)
297                         sum += (int)a10 [i];
298                 if (sum != 45)
299                         return 10;
300
301                 object[] a11 = new object [10];
302                 object o = new Object ();
303                 for (int i = 0; i < 10; ++i)
304                         a11 [i] = o;
305                 for (int i = 0; i < 10; ++i)
306                    if (a11 [i] != o)
307                                  return 11;
308
309                 FooStruct[] a12 = new FooStruct [10];
310                 for (int i = 0; i < 10; ++i)
311                         a12 [i] = new FooStruct (i);
312                 sum = 0;
313                 for (int i = 0; i < 10; ++i)
314                         sum += a12 [i].i;
315                 if (sum != 45)
316                         return 12;
317
318                 return 0;
319         }
320
321         [Category ("!INTERPRETER")]
322         public static int test_0_multi_dimension_arrays () {
323                 int sum;
324
325                 byte[,] a1 = new byte [10, 10];
326                 for (int i = 0; i < 10; ++i)
327                         a1 [i, i] = (byte)i;
328                 sum = 0;
329                 for (int i = 0; i < 10; ++i)
330                         sum += a1 [i, i];
331                 if (sum != 45)
332                         return 1;
333
334                 sbyte[,] a2 = new sbyte [10, 10];
335                 for (int i = 0; i < 10; ++i)
336                         a2 [i, i] = (sbyte)i;
337                 sum = 0;
338                 for (int i = 0; i < 10; ++i)
339                         sum += a2 [i, i];
340                 if (sum != 45)
341                         return 2;
342
343                 short[,] a3 = new short [10, 10];
344                 for (int i = 0; i < 10; ++i)
345                         a3 [i, i] = (short)i;
346                 sum = 0;
347                 for (int i = 0; i < 10; ++i)
348                         sum += a3 [i, i];
349                 if (sum != 45)
350                         return 3;
351
352                 ushort[,] a4 = new ushort [10, 10];
353                 for (int i = 0; i < 10; ++i)
354                         a4 [i, i] = (ushort)i;
355                 sum = 0;
356                 for (int i = 0; i < 10; ++i)
357                         sum += a4 [i, i];
358                 if (sum != 45)
359                         return 4;
360
361                 int[,] a5 = new int [10, 10];
362                 for (int i = 0; i < 10; ++i)
363                         a5 [i, i] = (int)i;
364                 sum = 0;
365                 for (int i = 0; i < 10; ++i)
366                         sum += a5 [i, i];
367                 if (sum != 45)
368                         return 5;
369
370                 uint[,] a6 = new uint [10, 10];
371                 for (int i = 0; i < 10; ++i)
372                         a6 [i, i] = (uint)i;
373                 sum = 0;
374                 for (int i = 0; i < 10; ++i)
375                         sum += (int)a6 [i, i];
376                 if (sum != 45)
377                         return 6;
378
379                 long[,] a7 = new long [10, 10];
380                 for (int i = 0; i < 10; ++i)
381                         a7 [i, i] = i;
382                 sum = 0;
383                 for (int i = 0; i < 10; ++i)
384                         sum += (int)a7 [i, i];
385                 if (sum != 45)
386                         return 7;
387
388                 ulong[,] a8 = new ulong [10, 10];
389                 for (int i = 0; i < 10; ++i)
390                         a8 [i, i] = (ulong)i;
391                 sum = 0;
392                 for (int i = 0; i < 10; ++i)
393                         sum += (int)a8 [i, i];
394                 if (sum != 45)
395                         return 8;
396
397                 float[,] a9 = new float [10, 10];
398                 for (int i = 0; i < 10; ++i)
399                         a9 [i, i] = (float)i;
400                 sum = 0;
401                 for (int i = 0; i < 10; ++i)
402                         sum += (int)a9 [i, i];
403                 if (sum != 45)
404                         return 9;
405
406                 double[,] a10 = new double [10, 10];
407                 for (int i = 0; i < 10; ++i)
408                         a10 [i, i] = i;
409                 sum = 0;
410                 for (int i = 0; i < 10; ++i)
411                         sum += (int)a10 [i, i];
412                 if (sum != 45)
413                         return 10;
414
415                 object[,] a11 = new object [10, 10];
416                 object o = new Object ();
417                 for (int i = 0; i < 10; ++i)
418                         a11 [i, i] = o;
419                 for (int i = 0; i < 10; ++i)
420                    if (a11 [i, i] != o)
421                                  return 11;
422
423                 FooStruct[,] a12 = new FooStruct [10, 10];
424                 for (int i = 0; i < 10; ++i)
425                         for (int j = 0; j < 10; ++j) {
426                                 /* This one calls Address */
427                                 a12 [i, j] = new FooStruct (i + j);
428
429                                 /* Test Set as well */
430                                 FooStruct s = new FooStruct (i + j);
431                                 a12 [i, j] = s;
432                         }
433                 sum = 0;
434                 for (int i = 0; i < 10; ++i)
435                         for (int j = 0; j < 10; ++j) {
436                                 /* This one calls Address */
437                                 sum += a12 [i, j].i;
438
439                                 /* Test Get as well */
440                                 FooStruct s = a12 [i, j];
441                                 sum += s.i;
442                         }
443                 if (sum != 1800)
444                         return 12;
445
446                 /* Null check */
447                 object[,] a13 = null;
448                 try {
449                         a13 [0, 0] = new Object ();
450                         return 13;
451                 } catch (NullReferenceException) {
452                 }
453
454                 return 0;
455         }
456
457         public static int test_100_3_dimensional_arrays () {
458         int[,,] test = new int[10, 10, 10];
459
460                 test [1, 1, 1] = 100;
461                 return test [1, 1, 1];
462         }
463
464         public static int test_100_4_dimensional_arrays () {
465         int[,,,] test = new int[10, 10, 10, 10];
466
467                 test [1, 1, 1, 1] = 100;
468                 return test [1, 1, 1, 1];
469         }
470
471         public static int test_0_bug_71454 () {
472                 int[,] a = new int[4,4];
473                 int[,] b = new int[4,4];
474                 for(int i = 0; i < 4; ++i) {
475                         b[0,0] = a[0,i % 4];
476                 }
477                 return 0;
478         }
479
480         public static int test_0_interface_array_cast () {
481                 try {
482                         object [] a = new ICloneable [2];
483                         ICloneable [] b = (ICloneable [])a;
484                 } catch {
485                         return 1;
486                 }
487                 return 0;
488         }
489
490         class Foo {
491                 public static Foo[][] foo;
492         }
493
494         public static int test_0_regress_74549 () {
495                 new Foo ();
496                 return 0;
497         }
498
499         public static int test_0_regress_75832 () {
500                 int[] table = new int[] { 0, 0 };
501                 
502                 int x = 0;
503                 
504                 int temp = -1 ^ x;
505                 temp = 2 + temp;
506                 int y = table[temp];
507
508                 return y;
509         }
510
511         class RefClass {
512         }
513
514         public static int test_0_stelem_ref_null_opt () {
515                 object[] arr = new RefClass [1];
516
517                 arr [0] = new RefClass ();
518                 arr [0] = null;
519
520                 return arr [0] == null ? 0 : 1;
521         }
522
523         public static int test_0_invalid_new_array_size () {
524                 int size;
525                 object res = null;
526                 size = -1;
527                 try {
528                         res = new float [size];
529                 } catch (OverflowException e) {
530
531                 } catch (Exception) {
532                         return 1;
533                 }
534                 if (res != null)
535                         return 2;
536
537                 size = -2147483648;
538                 try {
539                         res = new float [size];
540                 } catch (OverflowException e) {
541
542                 } catch (Exception) {
543                         return 3;
544                 }
545
546                 if (res != null)
547                         return 4;
548
549                 return 0;
550         }
551
552         [Category ("!INTERPRETER")]
553         public static int test_0_multidym_array_with_negative_lower_bound () {
554                 int[,] x = (int[,]) Array.CreateInstance(typeof (int), new int[] { 2, 2 }, new int[] { -2, -3 });
555
556                 if(x.GetLowerBound (0) != -2)
557                         return 1;
558                 if (x.GetLowerBound (1) != -3)
559                         return 2;
560
561                 x.SetValue (10, new int [] { -2, -3 });
562                 x.SetValue (20, new int [] { -2, -2 });
563                 x.SetValue (30, new int [] { -1, -3 });
564                 x.SetValue (40, new int [] { -1, -2 });
565
566                 try {
567                         x.SetValue (10, new int [] { -3, -3 });
568                         return 3;
569                 } catch (IndexOutOfRangeException) { }
570
571                 try {
572                         x.SetValue (10, new int [] { -2, -4 });
573                         return 4;
574                 } catch (IndexOutOfRangeException) { }
575
576                 try {
577                         x.SetValue (10, new int [] { 0, -3 });
578                         return 5;
579                 } catch (IndexOutOfRangeException) { }
580
581                 try {
582                         x.SetValue (10, new int [] { -1, -1 });
583                         return 6;
584                 } catch (IndexOutOfRangeException) { }
585
586                 if ((int)x.GetValue (new int [] { -2, -3 }) != 10)
587                         return 7;
588                 if ((int)x.GetValue (new int [] { -2, -2 }) != 20)
589                         return 8;
590                 if ((int)x.GetValue (new int [] { -1, -3 }) != 30)
591                         return 9;
592                 if ((int)x.GetValue (new int [] { -1, -2 }) != 40)
593                         return 10;
594
595                 try {
596                         x.GetValue (new int [] { -3, -3 });
597                         return 11;
598                 } catch (IndexOutOfRangeException) { }
599
600                 try {
601                         x.GetValue ( new int [] { -2, -4 });
602                         return 12;
603                 } catch (IndexOutOfRangeException) { }
604
605                 try {
606                         x.GetValue (new int [] { 0, -3 });
607                         return 13;
608                 } catch (IndexOutOfRangeException) { }
609
610                 try {
611                         x.GetValue (new int [] { -1, -1 });
612                         return 14;
613                 } catch (IndexOutOfRangeException) { }
614                 return 0;
615         }
616
617
618         public static int test_0_invalid_new_multi_dym_array_size () {
619                 int dym_size = 1;
620                 int size;
621                 object res = null;
622                 size = -1;
623                 try {
624                         res = new float [dym_size, size];
625                 } catch (OverflowException e) {
626
627                 } catch (Exception) {
628                         return 1;
629                 }
630                 if (res != null)
631                         return 2;
632
633                 size = -2147483648;
634                 try {
635                         res = new float [size, dym_size];
636                 } catch (OverflowException e) {
637
638                 } catch (Exception) {
639                         return 3;
640                 }
641
642                 if (res != null)
643                         return 4;
644
645                 return 0;
646         }
647
648         public enum IntEnum {
649                 A,B,C
650         }
651
652         public enum UintEnum : uint {
653                 A,B,C
654         }
655
656         static bool TryCast<T> (object o) {
657                 return o is T[];
658         }
659
660         public static int test_0_primitive_array_cast () {
661                 object a = new int[1];
662                 object b = new uint[1];
663                 object c = new IntEnum[1];
664                 object d = new UintEnum[1];
665
666                 object[] arr = new object[] { a, b, c, d };
667                 int err = 1;
668
669                 foreach (var v in arr) {
670                         if (!TryCast<int> (v))
671                                 return err;
672                         if (!TryCast<uint> (v))
673                                 return err + 1;
674                         if (!TryCast<IntEnum> (v))
675                                 return err + 2;
676                         if (!TryCast<UintEnum> (v))
677                                 return err + 3;
678                         err += 4;
679                 }
680
681                 foreach (var v in arr) {
682                         if (!(v is int[]))
683                                 return err;
684                         if (!(v is uint[]))
685                                 return err;
686                         if (!(v is IntEnum[]))
687                                 return err;
688                         if (!(v is UintEnum[]))
689                                 return err;
690                         err += 4;
691                 }
692                 return 0;
693         }
694
695         public static int test_0_intptr_array_cast () {
696                 object[] a = new object[] { new int[1], new uint[1] };
697                 object[] b = new object[] { new long[1], new ulong[1] };
698                 object[] c = new object[] { new IntPtr[1], new UIntPtr[1] };
699
700                 int err = 1;
701                 if (IntPtr.Size == 4) {
702                         foreach (var v in a) {
703                                 if (!(v is IntPtr[]))
704                                         return err;
705                                 if (!(v is IntPtr[]))
706                                         return err;
707                                 err += 2;
708                         }
709                         foreach (var v in b) {
710                                 if (v is IntPtr[])
711                                         return err;
712                                 if (v is IntPtr[])
713                                         return err;
714                                 err += 2;
715                         }
716
717                         foreach (var v in c) {
718                                 if (!(v is int[]))
719                                         return err;
720                                 if (!(v is uint[]))
721                                         return err;
722                                 err += 2;
723                         }
724                 } else {
725                         foreach (var v in a) {
726                                 if (v is IntPtr[])
727                                         return err;
728                                 if (v is IntPtr[])
729                                         return err;
730                                 err += 2;
731                         }
732                         foreach (var v in b) {
733                                 if (!(v is IntPtr[]))
734                                         return err;
735                                 if (!(v is IntPtr[]))
736                                         return err;
737                                 err += 2;
738                         }
739                         foreach (var v in c) {
740                                 if (!(v is long[]))
741                                         return err;
742                                 if (!(v is ulong[]))
743                                         return err;
744                                 err += 2;
745                         }
746                 }
747                 return 0;
748         }
749
750         public static int test_0_long_indices () {
751                 int[] arr = new int [10];
752                 int[,] arr2 = new int [10, 10];
753                 long index = 1;
754                 arr [index] = 5;
755                 if (arr [index] != 5)
756                         return 1;
757                 arr2 [index, index] = 5;
758                 if (arr2 [index, index] != 5)
759                         return 2;
760                 return 0;
761         }
762
763         // #7438
764         public static int test_0_ldelema_2_64bit () {
765         bool[,] test = new bool[201,201];
766         int x,y;
767         for(x=-100;x<100;x++) for(y=-100;y<100;y++){
768             test[x+100,y+100] = true;
769         }
770                 return 0;
771         }
772
773         static bool alloc_long (long l) {
774                 try {
775                         var arr = new byte[l];
776                         return false;
777                 } catch (Exception e) {
778                         return true;
779                 }
780         }
781
782         // #13544
783         [Category ("!INTERPRETER")]
784         public static int test_0_newarr_ovf () {
785                 if (!alloc_long (5000000000))
786                         return 1;
787                 if (!alloc_long (4000000000))
788                         return 2;
789                 if (!alloc_long (-1))
790                         return 3;
791                 if (!alloc_long (-4000000000))
792                         return 4;
793                 if (!alloc_long (-6000000000))
794                         return 5;
795                 return 0;
796         }
797
798         static int llvm_ldlen_licm (int[] arr) {
799                 int sum = 0;
800                 // The ldlen should be moved out of the loop
801                 for (int i = 0; i < arr.Length; ++i)
802                         sum += arr [i];
803                 return sum;
804         }
805
806         public static int test_10_llvm_ldlen_licm () {
807                 int[] arr = new int [10];
808                 for (int i = 0; i < 10; ++i)
809                         arr [i] = 1;
810                 return llvm_ldlen_licm (arr);
811         }
812 }
813
814