[jit] Fix the saving of the 'cfg->ret_var_set' flag when inlining, it was set to...
[mono.git] / mono / tests / generics-sharing.2.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Reflection;
4
5 namespace GenericSharingTest {
6
7 public delegate int IntVoidDelegate ();
8
9 public class ClassA {}
10 public class ClassB {}
11 public class ClassC {}
12
13 public class GenExc<T> : Exception {}
14
15 public class NonGen {
16         public static int field = 123;
17
18         public static void doThrow () {
19                 throw new GenExc<ClassA> ();
20         }
21 }
22
23 public class GenBi<S,T> {
24         public static int field = 123;
25         public static float floatField = 1.0f;
26
27         public static int staticMethod (int x) {
28                 return x + field;
29         }
30
31         public static void staticVoidMethod (int x) {
32                 field = x;
33         }
34
35         public static float staticFloatMethod () {
36                 return floatField;
37         }
38
39         public static long staticLongMethod (long x) {
40                 return x + field;
41         }
42
43         public static GenStruct<T> staticValueMethod (int x) {
44                 return new GenStruct<T> (x);
45         }
46 }
47
48 public struct GenStruct<T> {
49         public static int staticField;
50
51         public int field;
52         public int dummy1;
53         public int dummy2;
54         public int dummy3;
55
56         public GenStruct (int f) {
57                 field = f;
58                 dummy1 = dummy2 = dummy3 = 0;
59         }
60
61         public int method (int x) {
62                 return x + field;
63         }
64 }
65
66 public interface IGen<T> {
67         T[] iMethod ();
68         void voidIMethod (int x);
69         long longIMethod (long x);
70         float floatIMethod ();
71         GenStruct<T> valueIMethod (int x);
72 }
73
74 public class IGenImpl<T> : IGen<T> {
75         public int field;
76
77         public T[] iMethod () {
78                 return new T[3];
79         }
80
81         public void voidIMethod (int x) {
82                 field = x;
83         }
84
85         public long longIMethod (long x) {
86                 return x + 1;
87         }
88
89         public float floatIMethod () {
90                 return 1.0f;
91         }
92
93         public GenStruct<T> valueIMethod (int x) {
94                 return new GenStruct<T> (x);
95         }
96 }
97
98 public class GenA<T> {
99         public static T[] arr;
100
101         static GenA () {
102                 arr = new T [3];
103         }
104
105         public GenA () {}
106
107         public GenA<T> newGen () {
108                 return new GenA<T> ();
109         }
110
111         public GenA<int> newGenInt () {
112                 return new GenA<int> ();
113         }
114
115         public int getGenField () {
116                 return GenB<ClassA>.field;
117         }
118
119         public int getNonGenField () {
120                 return NonGen.field;
121         }
122
123         public int getGenStructStaticField () {
124                 return GenStruct<T>.staticField;
125         }
126
127         public T[] getArr () {
128                 return arr;
129         }
130
131         public T[] newArr () {
132                 return new T [3];
133         }
134
135         public GenA<T>[] newSelfArr () {
136                 return new GenA<T> [3];
137         }
138
139         public GenB<GenB<T>>[] newArrNested () {
140                 /*
141                 GenB<GenB<T>>[] arr = null;
142                 for (int i = 0; i < 10000000; ++i)
143                         arr = new GenB<GenB<T>> [3];
144                 */
145                 return new GenB<GenB<T>> [3];
146         }
147
148         public int hash (T obj) {
149                 return obj.GetHashCode ();
150         }
151
152         public T ident (T obj) {
153                 return obj;
154         }
155
156         public T cast (Object obj) {
157                 return (T)obj;
158         }
159
160         public GenStruct<T> structCast (Object obj) {
161                 return (GenStruct<T>)obj;
162         }
163
164         public Type ldtokenT () {
165                 return typeof (T);
166         }
167
168         public Type ldtokenIGenT () {
169                 return typeof (IGen<T>);
170         }
171
172         public Type ldtokenGenAIGenT () {
173                 return typeof (GenA<IGen<T>>);
174         }
175
176         public Type ldtokenGenB () {
177                 return typeof (GenB<>);
178         }
179
180         public GenStruct<T>? makeNullable (Object obj) {
181                 return (GenStruct<T>?)obj;
182         }
183
184         public object unmakeNullable (GenStruct<T>? obj) {
185                 return (object)obj;
186         }
187
188         public void except () {
189                 try {
190                         NonGen.doThrow ();
191                 }
192                 catch (GenExc<T>) {
193                         //Console.WriteLine("exception thrown");
194                 }
195         }
196
197         public static void staticExcept () {
198                 try {
199                         NonGen.doThrow ();
200                 }
201                 catch (GenExc<T>) {
202                         Console.WriteLine("exception thrown and caught");
203                 }
204         }
205
206         public static int staticField = 54321;
207
208         public static int staticMethod () {
209                 return staticField;
210         }
211
212         public static int staticMethodCaller () {
213                 return staticMethod ();
214         }
215
216         public static float staticFloatField = 1.0f;
217
218         public static float staticFloatMethod () {
219                 return staticFloatField;
220         }
221
222         public static int staticBiCaller (int x) {
223                 return GenBi<int,T>.staticMethod (x);
224         }
225
226         public static void staticBiVoidCaller (int x) {
227                 GenBi<int,T>.staticVoidMethod (x);
228         }
229
230         public static float staticBiFloatCaller () {
231                 return GenBi<int,T>.staticFloatMethod ();
232         }
233
234         public static GenStruct<T> staticBiValueCaller (int x) {
235                 return GenBi<int,T>.staticValueMethod (x);
236         }
237
238         public static int staticSharedBiCaller (int x) {
239                 return GenBi<T,T>.staticMethod (x);
240         }
241
242         public static void staticSharedBiVoidCaller (int x) {
243                 GenBi<T,T>.staticVoidMethod (x);
244         }
245
246         public static float staticSharedBiFloatCaller () {
247                 return GenBi<T,T>.staticFloatMethod ();
248         }
249
250         public static GenStruct<T> staticSharedBiValueCaller (int x) {
251                 return GenBi<T,T>.staticValueMethod (x);
252         }
253
254         public static long staticBiLongCaller (long x) {
255                 return GenBi<int, T>.staticLongMethod (x);
256         }
257
258         public int structCaller (int x) {
259                 GenStruct<GenA<T>> gs = new GenStruct<GenA<T>> (123);
260
261                 return gs.method (x);
262         }
263
264         public T[] callInterface (IGen<T> ig) {
265                 return ig.iMethod ();
266         }
267
268         public void callVoidInterface (IGen<T> ig, int x) {
269                 ig.voidIMethod (x);
270         }
271
272         public long callLongInterface (IGen<T> ig, long x) {
273                 return ig.longIMethod (x);
274         }
275
276         public float callFloatInterface (IGen<T> ig) {
277                 return ig.floatIMethod ();
278         }
279
280         public GenStruct<T> callValueInterface (IGen<T> ig, int x) {
281                 return ig.valueIMethod (x);
282         }
283 }
284
285 public class GenB<T> {
286         public static int field = 123;
287 }
288
289 public class GenC<T> {
290         public static int field ;
291
292         static GenC () {
293                 field = 1234;
294         }
295 }
296
297 public class StaticTest<T> {
298         static int stat;
299
300         public StaticTest (int x) {
301                 stat = x;
302         }
303
304         public int getStat () {
305                 return stat;
306         }
307
308         public int getOtherStat () {
309                 return StaticTest<Object>.stat;
310         }
311
312         public int getGenCStat () {
313                 return GenC<T>.field;
314         }
315 }
316
317 public class GenADeriv<T> : GenA<T> {
318         public static int otherField = 123;
319 }
320
321 public class GenABDeriv<T> : GenA<GenB<T>> {
322         public T[] newDerivArr () {
323                 return new T [3];
324         }
325 }
326
327 public class NonGenUser<T> where T : NonGen {
328         public int getNonGenField () {
329                 return NonGen.field;
330         }
331 }
332
333 public class AccessTest<T> {
334         private static int field = 123;
335
336         public int getOtherField () {
337                 return AccessTest<int>.field;
338         }
339 }
340
341 public class VirtualTest<T> {
342         public virtual T[] newArr () {
343                 return new T [3];
344         }
345 }
346
347 public class VirtualTestDeriv<T> : VirtualTest<T> {
348         public override T[] newArr () {
349                 return new T [4];
350         }
351 }
352
353 public class VirtualTestCaller<T> {
354         public T[] doCall (VirtualTest<T> vt) {
355                 return vt.newArr ();
356         }
357 }
358
359 public class MyCons<T> {
360         public T car;
361         public MyCons<T> cdr;
362
363         public static void printCar (T _car) {
364                 Console.WriteLine ("car " + _car.ToString () /* + " cdr " + _cdr.ToString () */);
365         }
366
367         public MyCons (T _car, MyCons<T> _cdr) {
368                 //printCar (_car);
369                 car = _car; cdr = _cdr;
370         }
371
372         public static MyCons<T> returnList (MyCons<T> l) { return l; }
373
374         public static MyCons<T> returnCdr (MyCons<T> cons) { return returnList(cons.cdr); }
375 }
376
377 public class MyPair<N,M> {
378         public N n;
379         public M m;
380
381         public MyPair (N _n, M _m) { n = _n; m = _m; }
382 }
383
384 public class MyDict<N,M> {
385         public MyPair<N,M> p;
386
387         public MyDict (N n, M m) { p = new MyPair<N,M> (n, m); }
388 }
389
390 public class RGCTXTest<T> {
391         public GenA<T>[] newAArr () {
392                 return new GenA<T> [3];
393         }
394 }
395
396 public class RGCTXTestSubA<T> : RGCTXTest<T> {
397         public GenB<T>[] newBArr () {
398                 return new GenB<T> [3];
399         }
400 }
401
402 public class RGCTXTestSubB<T> : RGCTXTest<T> {
403         public GenC<T>[] newCArr () {
404                 return new GenC<T> [3];
405         }
406 }
407
408 public class RGCTXTestSubASub : RGCTXTestSubA<ClassA> {
409 }
410
411 public class RGCTXTestSubASubSub<T> : RGCTXTestSubASub {
412         public GenC<T>[] newCArr () {
413                 return new GenC<T> [3];
414         }
415 }
416
417 public class main {
418         delegate void ActionDelegate ();
419
420         static bool haveError = false;
421
422         static void error (string message) {
423                 haveError = true;
424                 Console.WriteLine (message);
425         }
426
427         static void typeCheck (String method, Object obj, Type t) {
428                 if (obj.GetType () != t)
429                         error ("object from " + method + " should have type " + t.ToString () + " but has type " + obj.GetType ().ToString ());
430         }
431
432         static int callStaticMethod<T> () {
433                 return GenA<T>.staticMethod ();
434         }
435
436         static void checkException<T> (String method, ActionDelegate action) where T : Exception {
437                 try {
438                         try {
439                                 action ();
440                         } catch (T) {
441                                 return;
442                         }
443                 } catch (Exception exc) {
444                         error ("method " + method + " should have thrown " + typeof (T).ToString () + " but did throw " + exc);
445                 }
446         }
447
448         public static void work<T> (T obj, bool mustCatch) {
449                 EqualityComparer<T> comp = EqualityComparer<T>.Default;
450
451                 GenA<T> ga = new GenA<T> ();
452
453                 typeCheck ("newGen", ga.newGen (), typeof (GenA<T>));
454                 typeCheck ("newGenInt", ga.newGenInt (), typeof (GenA<int>));
455                 typeCheck ("getArr", ga.getArr (), typeof (T[]));
456                 typeCheck ("newArr", ga.newArr (), typeof (T[]));
457                 typeCheck ("newSelfArr", ga.newSelfArr (), typeof (GenA<T>[]));
458                 //ga.newArrNested ();
459                 typeCheck ("newArrNested", ga.newArrNested (), typeof (GenB<GenB<T>>[]));
460
461                 if (ga.getGenField () != 123)
462                         error ("getGenField");
463
464                 if (ga.getNonGenField () != 123)
465                         error ("getNonGenField");
466
467                 GenStruct<T>.staticField = 321;
468                 if (ga.getGenStructStaticField () != 321)
469                         error ("getGenStructStaticField");
470                 GenStruct<T>.staticField = -1;
471
472                 ga.hash (obj);
473
474                 if (!comp.Equals (ga.ident (obj), obj))
475                         error ("ident");
476
477                 if (!comp.Equals (ga.cast (obj), obj))
478                         error ("cast");
479                 if (typeof (T).IsValueType) {
480                         checkException<NullReferenceException> ("cast null value", delegate { ga.cast (null); });
481                 } else {
482                         if (ga.cast (null) != null)
483                                 error ("cast null");
484                 }
485
486                 GenStruct<T> genstructt = new GenStruct<T> (453);
487                 if (ga.structCast ((object)genstructt).field != 453)
488                         error ("structCast");
489                 checkException<NullReferenceException> ("structCast null", delegate { ga.structCast (null); });
490
491                 if (ga.makeNullable ((object)genstructt).Value.field != 453)
492                         error ("makeNullable");
493                 if (ga.makeNullable (null) != null)
494                         error ("makeNullable null");
495
496                 if (ga.ldtokenT () != typeof (T))
497                         error ("ldtokenT");
498                 if (ga.ldtokenIGenT () != typeof (IGen<T>))
499                         error ("ldtokenIGenT");
500                 if (ga.ldtokenGenAIGenT () != typeof (GenA<IGen<T>>))
501                         error ("ldtokenGenAIGenT");
502                 if (ga.ldtokenGenB () != typeof (GenB<>))
503                         error ("ldtokenGenB");
504
505                 if (callStaticMethod<T> () != 54321)
506                         error ("staticMethod");
507
508                 GenBi<int,T>.field = 123;
509                 if (GenA<T>.staticBiCaller (123) != 246)
510                         error ("staticBiCaller");
511                 GenA<T>.staticBiVoidCaller (1234);
512                 if (GenBi<int,T>.field != 1234)
513                         error ("staticBiVoidCaller");
514                 if (GenA<T>.staticBiFloatCaller () != 1.0f)
515                         error ("staticBiFloatCaller");
516                 if (GenA<T>.staticBiLongCaller (123) != 123 + 1234)
517                         error ("staticBiLongCaller");
518                 GenStruct<T> gs = GenA<T>.staticBiValueCaller (987);
519                 if (gs.field != 987)
520                         error ("staticBiValueCaller");
521
522                 GenBi<T,T>.field = 123;
523                 if (GenA<T>.staticSharedBiCaller (123) != 246)
524                         error ("staticSharedBiCaller");
525                 GenA<T>.staticSharedBiVoidCaller (1234);
526                 if (GenBi<T,T>.field != 1234)
527                         error ("staticSharedBiVoidCaller");
528                 if (GenA<T>.staticSharedBiFloatCaller () != 1.0f)
529                         error ("staticSharedBiFloatCaller");
530                 GenStruct<T> gss = GenA<T>.staticSharedBiValueCaller (987);
531                 if (gss.field != 987)
532                         error ("staticSharedBiValueCaller");
533
534                 IntVoidDelegate ivdel = new IntVoidDelegate (GenA<T>.staticMethod);
535                 if (ivdel () != 54321)
536                         error ("staticMethod delegate");
537
538                 Type gatype = typeof (GenA<T>);
539                 MethodInfo staticMethodInfo = gatype.GetMethod ("staticMethod");
540                 if ((Convert.ToInt32 (staticMethodInfo.Invoke (null, null))) != 54321)
541                         error ("staticMethod reflection");
542
543                 if (GenA<T>.staticMethodCaller () != 54321)
544                         error ("staticMethodCaller");
545
546                 if (GenA<T>.staticFloatMethod () != 1.0)
547                         error ("staticFloatMethod");
548
549                 if (ga.structCaller (234) != 357)
550                         error ("structCaller");
551
552                 IGenImpl<T> igi = new IGenImpl<T> ();
553
554                 typeCheck ("callInterface", ga.callInterface (igi), typeof (T[]));
555                 if (ga.callLongInterface (igi, 345) != 346)
556                         error ("callLongInterface");
557                 GenStruct<T> gst = ga.callValueInterface (igi, 543);
558                 if (gst.field != 543)
559                         error ("callValueInterface");
560                 ga.callVoidInterface (igi, 654);
561                 if (igi.field != 654)
562                         error ("callVoidInterface");
563                 if (ga.callFloatInterface (igi) != 1.0f)
564                         error ("callFloatInterface");
565
566                 new GenADeriv<T> ();
567
568                 if (mustCatch) {
569                         checkException<GenExc<ClassA>> ("except", delegate { ga.except (); });
570                         checkException<GenExc<ClassA>> ("staticExcept", delegate { GenA<T>.staticExcept (); });
571                 } else {
572                         ga.except ();
573                         GenA<T>.staticExcept ();
574                 }
575
576                 MyDict<T, ClassB> dtb = new MyDict<T, ClassB> (obj, new ClassB ());
577
578                 typeCheck ("MyPair", dtb.p, typeof (MyPair<T, ClassB>));
579
580                 GenABDeriv<T> gabd = new GenABDeriv<T> ();
581
582                 typeCheck ("GenABDeriv.newArr", gabd.newArr (), typeof (GenB<T>[]));
583                 typeCheck ("GenABDeriv.newDerivArr", gabd.newDerivArr (), typeof (T[]));
584
585                 RGCTXTest<T> rt = new RGCTXTest<T> ();
586                 RGCTXTestSubA<T> rtsa = new RGCTXTestSubA<T> ();
587                 RGCTXTestSubB<T> rtsb = new RGCTXTestSubB<T> ();
588                 RGCTXTestSubASub rtsas = new RGCTXTestSubASub ();
589                 RGCTXTestSubASubSub<T> rtsass = new RGCTXTestSubASubSub<T> ();
590
591                 typeCheck ("rtsass.newCArr", rtsass.newCArr (), typeof (GenC<T>[]));
592                 typeCheck ("rgsa.newBArr", rtsa.newBArr (), typeof (GenB<T>[]));
593                 typeCheck ("rg.newAArr", rt.newAArr (), typeof (GenA<T>[]));
594                 typeCheck ("rgsb.newCArr", rtsb.newCArr (), typeof (GenC<T>[]));
595
596                 /* repeat all for each class */
597                 typeCheck ("rtsass.newCArr", rtsass.newCArr (), typeof (GenC<T>[]));
598                 typeCheck ("rtsass.newBArr", rtsass.newBArr (), typeof (GenB<ClassA>[]));
599                 typeCheck ("rtsass.newAArr", rtsass.newAArr (), typeof (GenA<ClassA>[]));
600
601                 typeCheck ("rtsas.newBArr", rtsas.newBArr (), typeof (GenB<ClassA>[]));
602                 typeCheck ("rtsas.newAArr", rtsas.newAArr (), typeof (GenA<ClassA>[]));
603
604                 typeCheck ("rtsa.newBArr", rtsa.newBArr (), typeof (GenB<T>[]));
605                 typeCheck ("rtsa.newAArr", rtsa.newAArr (), typeof (GenA<T>[]));
606
607                 typeCheck ("rtsb.newCArr", rtsb.newCArr (), typeof (GenC<T>[]));
608                 typeCheck ("rtsb.newAArr", rtsb.newAArr (), typeof (GenA<T>[]));
609
610                 typeCheck ("rt.newAArr", rt.newAArr (), typeof (GenA<T>[]));
611         }
612
613         public static void virtualTest<T> (VirtualTest<T> vt, int len) {
614                 VirtualTestCaller<T> vtc = new VirtualTestCaller<T> ();
615                 T[] arr = vtc.doCall (vt);
616
617                 typeCheck ("virtualTest", arr, typeof (T[]));
618
619                 if (arr.Length != len)
620                         error ("virtualTest length");
621         }
622
623         public static void listTest () {
624                 MyCons<string> ls = new MyCons<string> ("abc", null);
625                 MyCons<string> cdr = MyCons<string>.returnCdr (ls);
626
627                 if (cdr != null)
628                         error ("cdr is not null");
629         }
630
631         public static int Main ()
632         {
633                 work<ClassA> (new ClassA (), false);
634                 work<ClassB> (new ClassB (), true);
635                 work<ClassB> (new ClassB (), true);
636                 work<ClassC> (new ClassC (), true);
637                 work<GenA<ClassA>> (new GenA<ClassA> (), true);
638                 work<int[]> (new int[3], true);
639                 work<int> (123, true);
640                 work<int?> (123, true);
641                 work<GenStruct<ClassA>?> (new GenStruct<ClassA> (123), true);
642                 work<GenStruct<ClassA>?> (null, true);
643
644                 StaticTest<ClassA> sa = new StaticTest<ClassA> (1234);
645                 StaticTest<ClassB> sb = new StaticTest<ClassB> (2345);
646
647                 if (sa.getStat () != 1234)
648                         error ("getStat");
649                 if (sb.getStat () != 2345)
650                         error ("getStat");
651                 if (sa.getOtherStat () != 0)
652                         error ("getOtherStat");
653                 if (sa.getGenCStat () != 1234)
654                         error ("getGenCStat A");
655                 if (sb.getGenCStat () != 1234)
656                         error ("getGenCStat B");
657
658                 NonGenUser<NonGen> ngu = new NonGenUser<NonGen> ();
659
660                 if (ngu.getNonGenField () != 123)
661                         error ("getNonGenField");
662
663                 AccessTest<ClassA> ata = new AccessTest<ClassA> ();
664
665                 if (ata.getOtherField () != 123)
666                         error ("getOtherField");
667
668                 VirtualTest<ClassA> vta = new VirtualTest<ClassA> ();
669                 VirtualTest<ClassB> vtb = new VirtualTestDeriv<ClassB> ();
670
671                 virtualTest<ClassA> (vta, 3);
672                 virtualTest<ClassB> (vtb, 4);
673
674                 listTest ();
675
676                 if (haveError)
677                         return 1;
678                 return 0;
679         }
680 }
681
682 }