Merge pull request #5714 from alexischr/update_bockbuild
[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         public static int test_0_multi_dimension_arrays () {
322                 int sum;
323
324                 byte[,] a1 = new byte [10, 10];
325                 for (int i = 0; i < 10; ++i)
326                         a1 [i, i] = (byte)i;
327                 sum = 0;
328                 for (int i = 0; i < 10; ++i)
329                         sum += a1 [i, i];
330                 if (sum != 45)
331                         return 1;
332
333                 sbyte[,] a2 = new sbyte [10, 10];
334                 for (int i = 0; i < 10; ++i)
335                         a2 [i, i] = (sbyte)i;
336                 sum = 0;
337                 for (int i = 0; i < 10; ++i)
338                         sum += a2 [i, i];
339                 if (sum != 45)
340                         return 2;
341
342                 short[,] a3 = new short [10, 10];
343                 for (int i = 0; i < 10; ++i)
344                         a3 [i, i] = (short)i;
345                 sum = 0;
346                 for (int i = 0; i < 10; ++i)
347                         sum += a3 [i, i];
348                 if (sum != 45)
349                         return 3;
350
351                 ushort[,] a4 = new ushort [10, 10];
352                 for (int i = 0; i < 10; ++i)
353                         a4 [i, i] = (ushort)i;
354                 sum = 0;
355                 for (int i = 0; i < 10; ++i)
356                         sum += a4 [i, i];
357                 if (sum != 45)
358                         return 4;
359
360                 int[,] a5 = new int [10, 10];
361                 for (int i = 0; i < 10; ++i)
362                         a5 [i, i] = (int)i;
363                 sum = 0;
364                 for (int i = 0; i < 10; ++i)
365                         sum += a5 [i, i];
366                 if (sum != 45)
367                         return 5;
368
369                 uint[,] a6 = new uint [10, 10];
370                 for (int i = 0; i < 10; ++i)
371                         a6 [i, i] = (uint)i;
372                 sum = 0;
373                 for (int i = 0; i < 10; ++i)
374                         sum += (int)a6 [i, i];
375                 if (sum != 45)
376                         return 6;
377
378                 long[,] a7 = new long [10, 10];
379                 for (int i = 0; i < 10; ++i)
380                         a7 [i, i] = i;
381                 sum = 0;
382                 for (int i = 0; i < 10; ++i)
383                         sum += (int)a7 [i, i];
384                 if (sum != 45)
385                         return 7;
386
387                 ulong[,] a8 = new ulong [10, 10];
388                 for (int i = 0; i < 10; ++i)
389                         a8 [i, i] = (ulong)i;
390                 sum = 0;
391                 for (int i = 0; i < 10; ++i)
392                         sum += (int)a8 [i, i];
393                 if (sum != 45)
394                         return 8;
395
396                 float[,] a9 = new float [10, 10];
397                 for (int i = 0; i < 10; ++i)
398                         a9 [i, i] = (float)i;
399                 sum = 0;
400                 for (int i = 0; i < 10; ++i)
401                         sum += (int)a9 [i, i];
402                 if (sum != 45)
403                         return 9;
404
405                 double[,] a10 = new double [10, 10];
406                 for (int i = 0; i < 10; ++i)
407                         a10 [i, i] = i;
408                 sum = 0;
409                 for (int i = 0; i < 10; ++i)
410                         sum += (int)a10 [i, i];
411                 if (sum != 45)
412                         return 10;
413
414                 object[,] a11 = new object [10, 10];
415                 object o = new Object ();
416                 for (int i = 0; i < 10; ++i)
417                         a11 [i, i] = o;
418                 for (int i = 0; i < 10; ++i)
419                    if (a11 [i, i] != o)
420                                  return 11;
421
422                 FooStruct[,] a12 = new FooStruct [10, 10];
423                 for (int i = 0; i < 10; ++i)
424                         for (int j = 0; j < 10; ++j) {
425                                 /* This one calls Address */
426                                 a12 [i, j] = new FooStruct (i + j);
427
428                                 /* Test Set as well */
429                                 FooStruct s = new FooStruct (i + j);
430                                 a12 [i, j] = s;
431                         }
432                 sum = 0;
433                 for (int i = 0; i < 10; ++i)
434                         for (int j = 0; j < 10; ++j) {
435                                 /* This one calls Address */
436                                 sum += a12 [i, j].i;
437
438                                 /* Test Get as well */
439                                 FooStruct s = a12 [i, j];
440                                 sum += s.i;
441                         }
442                 if (sum != 1800)
443                         return 12;
444
445                 /* Null check */
446                 object[,] a13 = null;
447                 try {
448                         a13 [0, 0] = new Object ();
449                         return 13;
450                 } catch (NullReferenceException) {
451                 }
452
453                 return 0;
454         }
455
456         public static int test_100_3_dimensional_arrays () {
457         int[,,] test = new int[10, 10, 10];
458
459                 test [1, 1, 1] = 100;
460                 return test [1, 1, 1];
461         }
462
463         public static int test_100_4_dimensional_arrays () {
464         int[,,,] test = new int[10, 10, 10, 10];
465
466                 test [1, 1, 1, 1] = 100;
467                 return test [1, 1, 1, 1];
468         }
469
470         public static int test_0_bug_71454 () {
471                 int[,] a = new int[4,4];
472                 int[,] b = new int[4,4];
473                 for(int i = 0; i < 4; ++i) {
474                         b[0,0] = a[0,i % 4];
475                 }
476                 return 0;
477         }
478
479         public static int test_0_interface_array_cast () {
480                 try {
481                         object [] a = new ICloneable [2];
482                         ICloneable [] b = (ICloneable [])a;
483                 } catch {
484                         return 1;
485                 }
486                 return 0;
487         }
488
489         class Foo {
490                 public static Foo[][] foo;
491         }
492
493         public static int test_0_regress_74549 () {
494                 new Foo ();
495                 return 0;
496         }
497
498         public static int test_0_regress_75832 () {
499                 int[] table = new int[] { 0, 0 };
500                 
501                 int x = 0;
502                 
503                 int temp = -1 ^ x;
504                 temp = 2 + temp;
505                 int y = table[temp];
506
507                 return y;
508         }
509
510         class RefClass {
511         }
512
513         public static int test_0_stelem_ref_null_opt () {
514                 object[] arr = new RefClass [1];
515
516                 arr [0] = new RefClass ();
517                 arr [0] = null;
518
519                 return arr [0] == null ? 0 : 1;
520         }
521
522         public static int test_0_invalid_new_array_size () {
523                 int size;
524                 object res = null;
525                 size = -1;
526                 try {
527                         res = new float [size];
528                 } catch (OverflowException e) {
529
530                 } catch (Exception) {
531                         return 1;
532                 }
533                 if (res != null)
534                         return 2;
535
536                 size = -2147483648;
537                 try {
538                         res = new float [size];
539                 } catch (OverflowException e) {
540
541                 } catch (Exception) {
542                         return 3;
543                 }
544
545                 if (res != null)
546                         return 4;
547
548                 return 0;
549         }
550
551         public static int test_0_multidym_array_with_negative_lower_bound () {
552                 int[,] x = (int[,]) Array.CreateInstance(typeof (int), new int[] { 2, 2 }, new int[] { -2, -3 });
553
554                 if(x.GetLowerBound (0) != -2)
555                         return 1;
556                 if (x.GetLowerBound (1) != -3)
557                         return 2;
558
559                 x.SetValue (10, new int [] { -2, -3 });
560                 x.SetValue (20, new int [] { -2, -2 });
561                 x.SetValue (30, new int [] { -1, -3 });
562                 x.SetValue (40, new int [] { -1, -2 });
563
564                 try {
565                         x.SetValue (10, new int [] { -3, -3 });
566                         return 3;
567                 } catch (IndexOutOfRangeException) { }
568
569                 try {
570                         x.SetValue (10, new int [] { -2, -4 });
571                         return 4;
572                 } catch (IndexOutOfRangeException) { }
573
574                 try {
575                         x.SetValue (10, new int [] { 0, -3 });
576                         return 5;
577                 } catch (IndexOutOfRangeException) { }
578
579                 try {
580                         x.SetValue (10, new int [] { -1, -1 });
581                         return 6;
582                 } catch (IndexOutOfRangeException) { }
583
584                 if ((int)x.GetValue (new int [] { -2, -3 }) != 10)
585                         return 7;
586                 if ((int)x.GetValue (new int [] { -2, -2 }) != 20)
587                         return 8;
588                 if ((int)x.GetValue (new int [] { -1, -3 }) != 30)
589                         return 9;
590                 if ((int)x.GetValue (new int [] { -1, -2 }) != 40)
591                         return 10;
592
593                 try {
594                         x.GetValue (new int [] { -3, -3 });
595                         return 11;
596                 } catch (IndexOutOfRangeException) { }
597
598                 try {
599                         x.GetValue ( new int [] { -2, -4 });
600                         return 12;
601                 } catch (IndexOutOfRangeException) { }
602
603                 try {
604                         x.GetValue (new int [] { 0, -3 });
605                         return 13;
606                 } catch (IndexOutOfRangeException) { }
607
608                 try {
609                         x.GetValue (new int [] { -1, -1 });
610                         return 14;
611                 } catch (IndexOutOfRangeException) { }
612                 return 0;
613         }
614
615
616         public static int test_0_invalid_new_multi_dym_array_size () {
617                 int dym_size = 1;
618                 int size;
619                 object res = null;
620                 size = -1;
621                 try {
622                         res = new float [dym_size, size];
623                 } catch (OverflowException e) {
624
625                 } catch (Exception) {
626                         return 1;
627                 }
628                 if (res != null)
629                         return 2;
630
631                 size = -2147483648;
632                 try {
633                         res = new float [size, dym_size];
634                 } catch (OverflowException e) {
635
636                 } catch (Exception) {
637                         return 3;
638                 }
639
640                 if (res != null)
641                         return 4;
642
643                 return 0;
644         }
645
646         public enum IntEnum {
647                 A,B,C
648         }
649
650         public enum UintEnum : uint {
651                 A,B,C
652         }
653
654         static bool TryCast<T> (object o) {
655                 return o is T[];
656         }
657
658         public static int test_0_primitive_array_cast () {
659                 object a = new int[1];
660                 object b = new uint[1];
661                 object c = new IntEnum[1];
662                 object d = new UintEnum[1];
663
664                 object[] arr = new object[] { a, b, c, d };
665                 int err = 1;
666
667                 foreach (var v in arr) {
668                         if (!TryCast<int> (v))
669                                 return err;
670                         if (!TryCast<uint> (v))
671                                 return err + 1;
672                         if (!TryCast<IntEnum> (v))
673                                 return err + 2;
674                         if (!TryCast<UintEnum> (v))
675                                 return err + 3;
676                         err += 4;
677                 }
678
679                 foreach (var v in arr) {
680                         if (!(v is int[]))
681                                 return err;
682                         if (!(v is uint[]))
683                                 return err;
684                         if (!(v is IntEnum[]))
685                                 return err;
686                         if (!(v is UintEnum[]))
687                                 return err;
688                         err += 4;
689                 }
690                 return 0;
691         }
692
693         public static int test_0_intptr_array_cast () {
694                 object[] a = new object[] { new int[1], new uint[1] };
695                 object[] b = new object[] { new long[1], new ulong[1] };
696                 object[] c = new object[] { new IntPtr[1], new UIntPtr[1] };
697
698                 int err = 1;
699                 if (IntPtr.Size == 4) {
700                         foreach (var v in a) {
701                                 if (!(v is IntPtr[]))
702                                         return err;
703                                 if (!(v is IntPtr[]))
704                                         return err;
705                                 err += 2;
706                         }
707                         foreach (var v in b) {
708                                 if (v is IntPtr[])
709                                         return err;
710                                 if (v is IntPtr[])
711                                         return err;
712                                 err += 2;
713                         }
714
715                         foreach (var v in c) {
716                                 if (!(v is int[]))
717                                         return err;
718                                 if (!(v is uint[]))
719                                         return err;
720                                 err += 2;
721                         }
722                 } else {
723                         foreach (var v in a) {
724                                 if (v is IntPtr[])
725                                         return err;
726                                 if (v is IntPtr[])
727                                         return err;
728                                 err += 2;
729                         }
730                         foreach (var v in b) {
731                                 if (!(v is IntPtr[]))
732                                         return err;
733                                 if (!(v is IntPtr[]))
734                                         return err;
735                                 err += 2;
736                         }
737                         foreach (var v in c) {
738                                 if (!(v is long[]))
739                                         return err;
740                                 if (!(v is ulong[]))
741                                         return err;
742                                 err += 2;
743                         }
744                 }
745                 return 0;
746         }
747
748         public static int test_0_long_indices () {
749                 int[] arr = new int [10];
750                 int[,] arr2 = new int [10, 10];
751                 long index = 1;
752                 arr [index] = 5;
753                 if (arr [index] != 5)
754                         return 1;
755                 arr2 [index, index] = 5;
756                 if (arr2 [index, index] != 5)
757                         return 2;
758                 return 0;
759         }
760
761         // #7438
762         public static int test_0_ldelema_2_64bit () {
763         bool[,] test = new bool[201,201];
764         int x,y;
765         for(x=-100;x<100;x++) for(y=-100;y<100;y++){
766             test[x+100,y+100] = true;
767         }
768                 return 0;
769         }
770
771         static bool alloc_long (long l) {
772                 try {
773                         var arr = new byte[l];
774                         return false;
775                 } catch (Exception e) {
776                         return true;
777                 }
778         }
779
780         // #13544
781         public static int test_0_newarr_ovf () {
782                 if (!alloc_long (5000000000))
783                         return 1;
784                 if (!alloc_long (4000000000))
785                         return 2;
786                 if (!alloc_long (-1))
787                         return 3;
788                 if (!alloc_long (-4000000000))
789                         return 4;
790                 if (!alloc_long (-6000000000))
791                         return 5;
792                 return 0;
793         }
794
795         static int llvm_ldlen_licm (int[] arr) {
796                 int sum = 0;
797                 // The ldlen should be moved out of the loop
798                 for (int i = 0; i < arr.Length; ++i)
799                         sum += arr [i];
800                 return sum;
801         }
802
803         public static int test_10_llvm_ldlen_licm () {
804                 int[] arr = new int [10];
805                 for (int i = 0; i < 10; ++i)
806                         arr [i] = 1;
807                 return llvm_ldlen_licm (arr);
808         }
809 }
810
811