Merge pull request #5675 from mono/glib-debug-symbols
[mono.git] / mcs / tests / dtest-006.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Reflection;
5
6 // Dynamic binary operator, unary operators and convert tests
7
8 public struct InverseLogicalOperator
9 {
10         bool value;
11         public InverseLogicalOperator (bool value)
12         {
13                 this.value = value;
14         }
15
16         public static bool operator true (InverseLogicalOperator u)
17         {
18                 return u.value;
19         }
20
21         public static bool operator false (InverseLogicalOperator u)
22         {
23                 return u.value;
24         }
25 }
26
27 public struct MyType
28 {
29         int value;
30         
31         public MyType (int value) : this ()
32         {
33                 this.value = value;
34         }
35         
36         public short ShortProp { get; set; }
37         
38         public override int GetHashCode ()
39         {
40                 throw new NotImplementedException ();
41         }
42
43         public static bool operator true (MyType a)
44         {
45                 return a.value != 1;
46         }
47
48         public static bool operator false (MyType a)
49         {
50                 return a.value == 0;
51         }
52
53         public static MyType operator + (MyType a, MyType b)
54         {
55                 return new MyType (a.value + b.value);
56         }
57
58         public static MyType operator - (MyType a, MyType b)
59         {
60                 return new MyType (a.value - b.value);
61         }
62
63         public static MyType operator / (MyType a, MyType b)
64         {
65                 return new MyType (a.value / b.value);
66         }
67
68         public static MyType operator * (MyType a, MyType b)
69         {
70                 return new MyType (a.value * b.value);
71         }
72
73         public static MyType operator % (MyType a, MyType b)
74         {
75                 return new MyType (a.value % b.value);
76         }
77
78         public static MyType operator &(MyType a, MyType b)
79         {
80                 return new MyType (a.value & b.value);
81         }
82
83         public static MyType operator | (MyType a, MyType b)
84         {
85                 return new MyType (a.value | b.value);
86         }
87
88         public static MyType operator ^ (MyType a, MyType b)
89         {
90                 return new MyType (a.value ^ b.value);
91         }
92
93         public static bool operator == (MyType a, MyType b)
94         {
95                 return a.value == b.value;
96         }
97
98         public static bool operator != (MyType a, MyType b)
99         {
100                 return a.value != b.value;
101         }
102         
103         public static bool operator > (MyType a, MyType b)
104         {
105                 return a.value > b.value;
106         }
107
108         public static bool operator < (MyType a, MyType b)
109         {
110                 return a.value < b.value;
111         }
112
113         public static bool operator >= (MyType a, MyType b)
114         {
115                 return a.value >= b.value;
116         }
117         
118         public static bool operator <= (MyType a, MyType b)
119         {
120                 return a.value <= b.value;
121         }
122
123         public static bool operator ! (MyType a)
124         {
125                 return a.value > 0;
126         }
127
128         public static int operator ~ (MyType a)
129         {
130                 return ~a.value;
131         }
132
133         public static MyType operator ++ (MyType a)
134         {
135                 return new MyType (a.value * 2);
136         }
137
138         public static MyType operator -- (MyType a)
139         {
140                 return new MyType (a.value / 2);
141         }
142
143         public static int operator >> (MyType a, int b)
144         {
145                 return a.value >> b;
146         }
147         
148         public static int operator << (MyType a, int b)
149         {
150                 return a.value << b;
151         }
152         
153         public static MyType operator - (MyType a)
154         {
155                 return new MyType (-a.value);
156         }
157         
158         public static MyType operator + (MyType a)
159         {
160                 return new MyType (334455); // magic number
161         }
162
163         public override string ToString ()
164         {
165                 return value.ToString ();
166         }
167 }
168
169
170 class MyTypeExplicit
171 {
172         int value;
173         
174         public MyTypeExplicit (int value)
175         {
176                 this.value = value;
177         }
178         
179         public static explicit operator int (MyTypeExplicit m)
180         {
181                 return m.value;
182         }
183 }
184
185 struct MyTypeImplicitOnly
186 {
187         short b;
188
189         public MyTypeImplicitOnly (short b)
190         {
191                 this.b = b;
192         }
193
194         public static implicit operator short (MyTypeImplicitOnly m)
195         {
196                 return m.b;
197         }
198
199         public static implicit operator bool (MyTypeImplicitOnly m)
200         {
201                 return m.b != 0;
202         }
203 }
204
205 enum MyEnum : byte
206 {
207         Value_1 = 1,
208         Value_2 = 2
209 }
210
211 enum MyEnumUlong : ulong
212 {
213         Value_1 = 1,
214         Value_2 = 2
215 }
216
217
218 class Tester
219 {
220         delegate void EmptyDelegate ();
221         event Action ev_assign;
222
223         static void Assert<T> (T expected, T value, string name)
224         {
225                 if (!EqualityComparer<T>.Default.Equals (expected, value)) {
226                         name += ": ";
227                         throw new ApplicationException (name + expected + " != " + value);
228                 }
229         }
230
231         static void AssertChecked<T> (Func<T> expected, T value, string name)
232         {
233                 try {
234                         Assert (expected (), value, name);
235                         throw new ApplicationException (name + ": OverflowException expected");
236                 } catch (OverflowException) {
237                         // passed
238                 }
239         }
240
241         static void AssertChecked (Action expected, string name)
242         {
243                 try {
244                         expected ();
245                         throw new ApplicationException (name + ": OverflowException expected");
246                 } catch (OverflowException) {
247                         // passed
248                 }
249         }
250
251 #pragma warning disable 169
252
253         void AddTest ()
254         {
255                 dynamic d = 5;
256
257                 int v = 2;
258                 Assert (d + v, 7, "#1");
259                 double v2 = 0.5;
260                 Assert (d + v2, 5.5, "#1a");
261
262                 d = new MyType (5);
263                 MyType v3 = new MyType (30);
264                 Assert (d + v3, new MyType (35), "#3");
265                 dynamic d3 = new MyType (-7);
266                 Assert<MyType> (d3 + new MyType (6), new MyType (-1), "#3a");
267
268                 d3 = new MyTypeImplicitOnly (6);
269                 Assert (d3 + new MyTypeImplicitOnly (11), 17, "#3b");
270
271                 d = new MyTypeImplicitOnly (5);
272                 decimal v4 = 4m;
273                 Assert (d + v4, 9m, "#4");
274         }
275
276         void AddNullableTest ()
277         {
278                 dynamic d = 5;
279
280                 int? v2 = null;
281                 Assert<int?> (d + v2, null, "#1");
282                 Assert<int?> (d + null, null, "#1a");
283                 Assert<int?> (null + d, null, "#1b");
284
285                 v2 = -2;
286                 Assert (d + v2, 3, "#2");
287                 dynamic d2 = (int?) -2;
288                 Assert (d2 + 1, -1, "#2a");
289
290                 d = new MyType (5);
291                 MyType? v3 = new MyType (30);
292                 Assert (d + v3, new MyType (35), "#3");
293                 dynamic d3 = new MyType? (new MyType (-7));
294                 Assert (d3 + new MyType (6), new MyType (-1), "#3a");
295                 Assert<MyType?> (d3 + null, null, "#3b");
296
297                 d = new MyTypeImplicitOnly (5);
298                 decimal? v4 = 4m;
299                 Assert (d + v4, 9m, "#4");
300                 v4 = null;
301                 Assert<decimal?> (d + v4, null, "#4a");
302         }
303         
304         void AddEnumTest ()
305         {
306                 dynamic d = MyEnum.Value_1;
307
308                 Assert (d + 1, MyEnum.Value_2, "#1");
309
310                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
311                 Assert (d2 + (byte) 1, MyEnumUlong.Value_2, "#2");
312                 Assert<MyEnumUlong?> (d2 + null, null, "#2a");
313                 
314                 // CSC: Invalid System.InvalidOperationException
315                 Assert<MyEnum?> (d + null, null, "#1");
316         }
317         
318         void AddCheckedTest ()
319         {
320                 checked {
321                         dynamic d = 5;
322
323                         int v = int.MaxValue;
324                         AssertChecked (() => d + v, 7, "#1");
325
326                         int? v2 = v;
327                         AssertChecked (() => d + v2, null, "#2");
328
329                         d = new MyType (3);
330                         MyType v3 = new MyType (int.MaxValue);
331                         Assert (new MyType (-2147483646), d + v3, "#3");
332                 }
333         }
334         
335         void AddStringTest ()
336         {
337                 dynamic d = "foo";
338                 string v = "->";
339                 Assert (d + v, "foo->", "#1");
340                 Assert (d + 1, "foo1", "#1a");
341                 Assert (d + null, "foo", "#1b");
342                 Assert (d + 1 + v, "foo1->", "#1a");
343
344                 uint? v2 = 4;
345                 Assert (d + v2, "foo4", "#2");
346         }
347
348         void AddAssignTest ()
349         {
350                 dynamic d = 5;
351
352                 int v = 2;
353                 d += v;
354                 Assert (d, 7, "#1");
355
356                 d = 5.0;
357                 double v2 = 0.5;
358                 d += v2;
359                 Assert (d, 5.5, "#1a");
360                 d += v;
361                 Assert (d, 7.5, "#1b");
362
363                 dynamic d3 = new MyType (-7);
364                 d3 += new MyType (6);
365                 Assert<MyType> (d3, new MyType (-1), "#3");
366
367                 d = 5m;
368                 decimal v4 = 4m;
369                 d += v4;
370                 Assert (d, 9m, "#4");
371         }
372
373         void AddAssignNullableTest ()
374         {
375                 dynamic d = (int?) 5;
376
377                 // FEATURE
378                 // For now it's impossible to use nullable compound assignment
379                 // due to the way how DLR works. GetType () on nullable object returns
380                 // underlying type and not nullable type, that means that
381                 // C# binder is initialized with wrong operand type and any operation
382                 // fails to resolve
383 /*
384                 long? v2 = null;
385                 d += v2;
386                 Assert<int?> (d, null, "#1");
387                 d += null;
388                 Assert<int?> (d, null, "#1a");
389
390                 long? l = (long?) 3;
391                 d = l;
392                 v2 = -2;
393                 d += v2;
394                 Assert (d, 3, "#2");
395                 d = (int?) -2;
396                 d += 1;
397                 Assert (d, -1, "#2a");
398
399                 MyType? v3 = new MyType (30);
400                 d += v3;
401                 Assert (d, new MyType (35), "#3");
402                 dynamic d3 = new MyType? (new MyType (-7));
403                 Assert (d3 + new MyType (6), new MyType (-1), "#3a");
404                 Assert<MyType?> (d3 + null, null, "#3b");
405
406                 decimal? v4 = 4m;
407                 d = 2m;
408                 d += v4;
409                 Assert (d, 9m, "#4");
410                 d += null;
411                 Assert<decimal?> (d, null, "#4a");
412  */
413         }
414
415         void AddAssignEnumTest ()
416         {
417                 dynamic d = MyEnum.Value_1;
418
419                 d = MyEnum.Value_1;
420                 d += 1;
421                 Assert (d, MyEnum.Value_2, "#2");
422
423                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
424                 d2 += (byte) 1;
425                 Assert (d2, MyEnumUlong.Value_2, "#3");
426         }
427
428         void AddAssignCheckedTest ()
429         {
430                 checked {
431                         dynamic d = 5;
432
433                         int v = int.MaxValue;
434                         AssertChecked (() => { d += v; Assert (d, 0, "#1-"); }, "#1");
435
436                         d = new MyType (5);
437                         MyType v3 = new MyType (int.MaxValue);
438                         d += v3;
439                         Assert (d, new MyType (-2147483644), "#3-");
440                 }
441         }
442
443         void AddAssignStringTest ()
444         {
445                 dynamic d = "foo";
446                 string v = "->";
447                 d += v;
448                 Assert (d, "foo->", "#1");
449
450                 d = "foo";
451                 d += 1;
452                 Assert (d, "foo1", "#1a");
453
454                 d += null;
455                 Assert (d, "foo1", "#1b");
456
457                 uint? v2 = 4;
458                 d = "foo";
459                 d += v2;
460                 Assert (d, "foo4", "#2");
461         }
462
463         void AddAssignEvent ()
464         {
465                 dynamic d = null;
466                 
467                 // FIXME: Will have to special case events
468                 // ev_assign += d;
469         }
470
471         void AndTest ()
472         {
473                 dynamic d = true;
474
475                 var v = false;
476                 Assert (d & v, false, "#1");
477                 Assert (d & true, true, "#1a");
478
479                 d = 42;
480                 var v2 = 62;
481                 Assert (d & v2, 42, "#2");
482                 Assert (d & 0, 0, "#2a");
483
484                 d = new MyType (10);
485                 MyType v3 = new MyType (30);
486                 Assert (d & v3, new MyType (10), "#3");
487                 dynamic d3 = new MyType (-7);
488                 Assert<MyType> (d3 & new MyType (6), new MyType (0), "#3a");
489
490                 d3 = new MyTypeImplicitOnly (6);
491                 Assert (d3 & 11, 2, "#3b");
492         }
493
494         void AndTestEnum ()
495         {
496                 dynamic d = MyEnum.Value_1;
497
498                 Assert<MyEnum?> (d & null, null, "#1");
499
500                 Assert (d & d, MyEnum.Value_1, "#2");
501
502                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
503                 Assert<MyEnumUlong> (d2 & MyEnumUlong.Value_2, 0, "#3");
504         }
505
506         void AndTestNullable ()
507         {
508                 dynamic d = 5;
509
510                 int? v2 = null;
511                 Assert<int?> (d & v2, null, "#1");
512                 Assert<int?> (d & null, null, "#1a");
513                 Assert<int?> (null & d, null, "#1b");
514
515                 v2 = -2;
516                 Assert (d & v2, 4, "#2");
517                 dynamic d2 = (int?) -2;
518                 Assert (d2 & 1, 0, "#2a");
519
520                 d = new MyType (22);
521                 MyType? v3 = new MyType (30);
522                 Assert (d & v3, new MyType (22), "#3");
523                 dynamic d3 = new MyType? (new MyType (-7));
524                 Assert (d3 & new MyType (6), new MyType (0), "#3a");
525                 Assert<MyType?> (d3 + null, null, "#3b");
526
527                 dynamic a = (bool?) true;
528                 dynamic b = (bool?) null;
529                 Assert (a & b, (bool?)null, "#4a");
530                 Assert (b & a, (bool?)null, "#4b");
531         }
532
533         void AndAssignedTest ()
534         {
535                 dynamic d = true;
536
537                 var v = false;
538                 d &= v;
539                 Assert (d, false, "#1");
540                 d = true;
541                 d &= true;
542                 Assert (d, true, "#1a");
543
544                 d = 42;
545                 var v2 = 62;
546                 d &= v2;
547                 Assert (d, 42, "#2");
548
549                 MyType v3 = new MyType (30);
550                 dynamic d3 = new MyType (-7);
551                 d3 &= new MyType (6);
552                 Assert<MyType> (d3, new MyType (0), "#3");
553         }
554
555         void AndAssignedTestEnum ()
556         {
557                 dynamic d = MyEnum.Value_1;
558                 d &= MyEnum.Value_2;
559                 Assert<MyEnum>(d, 0, "#1");
560
561                 d = MyEnum.Value_2;
562                 d &= d;
563                 Assert (d, MyEnum.Value_2, "#2");
564
565                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
566                 Assert<MyEnumUlong> (d2 & MyEnumUlong.Value_2, 0, "#3");
567         }
568
569         void AndAlsoTest ()
570         {
571                 dynamic d = true;
572
573                 var v = false;
574                 Assert<bool> (d && v, false, "#1");
575                 
576                 Assert (d && true, true, "#1a");
577
578                 d = true;
579                 Assert (d && d, true, "#2");
580
581                 dynamic d3 = new MyType (-7);
582                 Assert<MyType> (d3 && new MyType (6), new MyType (0), "#3");
583         }
584
585         void DivideTest ()
586         {
587                 dynamic d = 5;
588
589                 int v = 2;
590                 Assert (d / v, 2, "#1");
591
592                 d = new MyType (5);
593                 MyType v3 = new MyType (30);
594                 Assert (d / v3, new MyType (0), "#3");
595                 dynamic d3 = new MyType (-7);
596                 Assert<MyType> (d3 + new MyType (6), new MyType (-1), "#3a");
597
598                 d = new MyTypeImplicitOnly (6);
599                 decimal v4 = 4m;
600                 Assert (d / v4, 1.5m, "#4");
601         }
602
603         void DivideNullableTest ()
604         {
605                 dynamic d = 5;
606
607                 double? v2 = null;
608                 Assert<double?> (d / v2, null, "#1");
609                 Assert<double?> (d / null, null, "#1a");
610                 Assert<double?> (null / d, null, "#1b");
611
612                 v2 = -2;
613                 Assert (d / v2, -2.5, "#2");
614                 dynamic d2 = (int?) -2;
615                 Assert (d2 / 1, -2, "#2a");
616
617                 d = new MyType (5);
618                 MyType? v3 = new MyType (30);
619                 Assert (d / v3, new MyType (0), "#3");
620                 dynamic d3 = new MyType? (new MyType (-7));
621                 Assert (d3 / new MyType (6), new MyType (-1), "#3a");
622                 Assert<MyType?> (d3 + null, null, "#3b");
623
624                 d = new MyTypeImplicitOnly (5);
625                 decimal? v4 = 4m;
626                 Assert (d / v4, 1.25m, "#4");
627                 v4 = null;
628                 Assert<decimal?> (d / v4, null, "#4a");
629         }
630
631         void DivideCheckedTest ()
632         {
633                 checked {
634                         // TODO:
635                 }
636         }
637
638         void DivideAssignTest ()
639         {
640                 dynamic d = 5;
641
642                 int v = 2;
643                 d /= v;
644                 Assert (d, 2, "#1");
645
646                 d = 5.0;
647                 double v2 = 0.5;
648                 d /= v2;
649                 Assert (d, 10, "#1a");
650                 d /= v;
651                 Assert (d, 5, "#1b");
652
653                 dynamic d3 = new MyType (-7);
654                 d3 /= new MyType (6);
655                 Assert<MyType> (d3, new MyType (-1), "#3");
656
657                 d = 5m;
658                 decimal v4 = 4m;
659                 d /= v4;
660                 Assert (d, 1.25m, "#4");
661         }
662
663         void DivideAssignCheckedTest ()
664         {
665                 checked {
666                         // TODO:
667                 }
668         }
669
670         void ConvertImplicitTest ()
671         {
672                 dynamic d = 3;
673                 decimal v1 = d;
674                 Assert (3m, v1, "#1");
675
676                 d = new MyTypeImplicitOnly (5);
677                 int v2 = d;
678                 Assert (5, v2, "#2");
679
680                 d = (byte) 4;
681                 int v3 = d;
682                 Assert (4, v3, "#3");
683
684                 int[] v4 = new int[] { d };
685                 Assert (4, v4[0], "#4");
686
687                 d = true;
688                 var v5 = new [] { d, 1 };
689                 Assert (true, v5[0], "#5");
690                 Assert (1, v5[1], "#5a");
691
692                 d = "aa";
693                 bool b = false;
694                 var r = b ? d : "ss";
695                 Assert ("ss", r, "#6");
696                 
697                 var v = new [] { d, 1 };
698                 Assert ("aa", v [0], "#7");
699                 
700                 dynamic [,] a = new dynamic [,] { { 1, 2 }, { 'b', 'x' } };
701                 Assert (2, a [0, 1], "#8");
702                 Assert ('x', a [1, 1], "#8a");
703         }
704
705         int ConvertImplicitReturnTest ()
706         {
707                 dynamic d = (byte) 3;
708                 return d;
709         }
710
711         IEnumerable<string> ConvertImplicitReturnTest_2 ()
712         {
713                 dynamic d = "aaa";
714                 yield return d;
715         }
716
717         void ConvertExplicitTest ()
718         {
719                 dynamic d = 300;
720                 Assert (44, (byte) d, "#1");
721                 Assert<byte?> (44, (byte?) d, "#1a");
722
723                 d = 3m;
724                 Assert (3, d, "#2");
725
726                 d = new MyTypeImplicitOnly (5);
727                 Assert (5, (int) d, "#3");
728
729                 d = new MyTypeExplicit (-2);
730                 Assert (-2, (int) d, "#4");
731
732                 d = null;
733                 Assert (null, (object) d, "#5");
734         }
735
736         void ConvertExplicitCheckedTest ()
737         {
738                 checked {
739                         dynamic d = 300;
740                         AssertChecked (() => (byte) d, 7, "#1");
741
742                         d = ulong.MaxValue;
743                         AssertChecked<uint?> (() => (uint?) d, 2, "#2");
744                 }
745         }
746         
747         void ConvertArray ()
748         {
749                 dynamic idx = (uint) 1;
750                 var arr = new int [5];
751                 arr [idx] = 2;
752                 Assert (2, arr [idx], "#1");
753         }
754
755         void EqualTest ()
756         {
757                 dynamic d = 5;
758
759                 int v = 2;
760                 Assert (d == v, false, "#1");
761                 double v2 = 5;
762                 Assert (d == v2, true, "#1a");
763
764                 d = true;
765                 Assert (d == false, false, "#2");
766                 bool b2 = true;
767                 Assert (d == b2, true, "#2a");
768
769                 d = new MyType (30);
770                 MyType v3 = new MyType (30);
771                 Assert (d == v3, true, "#3");
772                 dynamic d3 = new MyTypeImplicitOnly (-7);
773                 Assert (d3 == 11, false, "#3b");
774                 
775                 d = 2m;
776                 decimal v4 = 4m;
777                 Assert (d == v4, false, "#4");
778                 Assert (d == 2m, true, "#4a");
779                 
780                 d = null;
781                 Assert (d == null, true, "#5");
782         }
783
784         void EqualNullableTest ()
785         {
786                 dynamic d = 5;
787
788                 int? v2 = null;
789                 Assert (d == v2, false, "#1");
790                 Assert (d == null, false, "#1a");
791                 Assert (null == d, false, "#1b");
792
793                 v2 = -2;
794                 Assert (d == v2, false, "#2");
795                 dynamic d2 = (int?) -2;
796                 Assert (d2 == 1, false, "#2a");
797                 d2 = (uint?) 44;
798                 Assert (d2 == 44, true, "#2b");
799
800                 d = new MyType (30);
801                 MyType? v3 = new MyType (30);
802                 Assert (d == v3, true, "#3");
803                 dynamic d3 = new MyType? (new MyType (-7));
804                 Assert (d3 == new MyType (6), false, "#3a");
805                 Assert (d3 == null, false, "#3b");
806                 
807                 d = 4.1m;
808                 decimal? v4 = 4m;
809                 Assert (d == v4, false, "#4");
810                 v4 = null;
811                 Assert (d == v4, false, "#4a");
812
813                 d = (bool?) true;
814                 Assert (d == true, true, "#5");
815                 Assert (d == null, false, "#5a");
816                 Assert (d == false, false, "#5b");
817         }
818
819         void EqualEnumTest ()
820         {
821                 dynamic d = MyEnum.Value_1;
822
823                 Assert (d == null, false, "#1");
824
825                 Assert (d == MyEnum.Value_1, true, "#2");
826                 Assert (d == 0, false, "#2a");
827
828                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
829                 Assert (d2 == MyEnumUlong.Value_2, true, "#3");
830                 Assert (d2 == null, false, "#3a");
831         }
832
833         void EqualStringTest ()
834         {
835                 dynamic d = "text";
836
837                 Assert (d == "te", false, "#1");
838                 Assert (d == "text", true, "#1a");
839                 Assert (d == null, false, "#1b");
840         }
841
842         void EqualDelegateTest ()
843         {
844                 dynamic d = this;
845
846 //              Assert (d == delegate { }, true, "#1");
847
848                 EmptyDelegate b = EqualDelegateTest;
849                 d = b;
850
851                 //Assert (d == EqualDelegateTest, true, "#2");
852         
853 /*
854
855         void EqualTestDelegate_2 ()
856         {
857                 EmptyDelegate ed = delegate () {};
858
859                 Expression<Func<EmptyDelegate, EmptyDelegate, bool>> e2 = (a, b) => a == b;
860                 AssertNodeType (e2, ExpressionType.Equal);
861                 Assert (false, e2.Compile ().Invoke (delegate () {}, null));
862                 Assert (false, e2.Compile ().Invoke (delegate () {}, delegate {}));
863                 Assert (false, e2.Compile ().Invoke (ed, delegate {}));
864                 Assert (true, e2.Compile ().Invoke (ed, ed));
865 */
866         }
867
868         void ExclusiveOrTest ()
869         {
870                 dynamic d = true;
871
872                 var v = false;
873                 Assert (d ^ v, true, "#1");
874                 Assert (d ^ true, false, "#1a");
875
876                 d = 42;
877                 var v2 = 62;
878                 Assert (d ^ v2, 20, "#2");
879                 Assert (d ^ 0, 42, "#2a");
880
881                 d = new MyType (42);
882                 MyType v3 = new MyType (30);
883                 Assert (d ^ v3, new MyType (52), "#3");
884                 dynamic d3 = new MyType (-7);
885                 Assert<MyType> (d3 ^ new MyType (6), new MyType (-1), "#3a");
886
887                 d3 = new MyTypeImplicitOnly (-7);
888                 Assert (d3 ^ 11, -14, "#3b");
889         }
890
891         void ExclusiveOrNullableTest ()
892         {
893                 dynamic d = 5;
894
895                 int? v2 = null;
896                 Assert<int?> (d ^ v2, null, "#1");
897                 Assert<int?> (d ^ null, null, "#1a");
898                 Assert<int?> (null ^ d, null, "#1b");
899
900                 v2 = -2;
901                 Assert (d ^ v2, -5, "#2");
902                 dynamic d2 = (int?) -2;
903                 Assert (d2 ^ 1, -1, "#2a");
904
905                 d = new MyType (5);
906                 MyType? v3 = new MyType (30);
907                 Assert (d ^ v3, new MyType (27), "#3");
908                 dynamic d3 = new MyType? (new MyType (-7));
909                 Assert (d3 ^ new MyType (6), new MyType (-1), "#3a");
910                 Assert<MyType?> (d3 ^ null, null, "#3b");
911         }
912
913         void ExclusiveOrTestEnum ()
914         {
915                 dynamic d = MyEnum.Value_1;
916
917                 Assert<MyEnum?> (d ^ null, null, "#1");
918
919                 Assert<MyEnum> (d ^ d, 0, "#2");
920
921                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
922                 Assert<MyEnumUlong> (d2 ^ MyEnumUlong.Value_2, (MyEnumUlong) 3, "#3");
923         }
924
925         void ExclusiveOrAssignedTest ()
926         {
927                 dynamic d = true;
928
929                 var v = false;
930                 d ^= v;
931                 Assert (d, true, "#1");
932                 d = true;
933                 d ^= true;
934                 Assert (d, false, "#1a");
935
936                 d = 42;
937                 var v2 = 62;
938                 d ^= v2;
939                 Assert (d, 20, "#2");
940
941                 MyType v3 = new MyType (30);
942                 dynamic d3 = new MyType (-7);
943                 d3 ^= new MyType (6);
944                 Assert (d3, new MyType (-1), "#3");
945         }
946
947         void ExclusiveOrAssignedTestEnum ()
948         {
949                 dynamic d = MyEnum.Value_1;
950                 d ^= MyEnum.Value_2;
951                 Assert<MyEnum>(d, (MyEnum) 3, "#1");
952
953                 d = MyEnum.Value_2;
954                 d ^= d;
955                 Assert<MyEnum> (d, 0, "#2");
956
957                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
958                 Assert (d2 ^ MyEnumUlong.Value_2, (MyEnumUlong)3, "#3");
959         }
960
961         void GreaterThanTest ()
962         {
963                 dynamic d = 5;
964
965                 int v = 2;
966                 Assert (d > v, true, "#1");
967                 double v2 = 5;
968                 Assert (d > v2, false, "#1a");
969
970                 d = 4.6;
971                 Assert (d > 4.59, true, "#2");
972                 var b2 = 4.6;
973                 Assert (d > b2, false, "#2a");
974
975                 d = new MyType (30);
976                 MyType v3 = new MyType (30);
977                 Assert (d > v3, false, "#3");
978                 dynamic d3 = new MyType (-7);
979                 Assert (d3 > new MyType (6), false, "#3a");
980
981                 d3 = new MyTypeImplicitOnly (-7);
982                 Assert (d3 > 11, false, "#3b");
983
984                 d = 2m;
985                 decimal v4 = 4m;
986                 Assert (d > v4, false, "#4");
987                 Assert (d > 2m, false, "#4a");
988         }
989
990         void GreaterThanNullableTest ()
991         {
992                 dynamic d = 5;
993
994                 int? v2 = null;
995                 Assert (d > v2, false, "#1");
996                 Assert (d > null, false, "#1a");
997                 Assert (null > d, false, "#1b");
998
999                 v2 = -2;
1000                 Assert (d > v2, true, "#2");
1001                 dynamic d2 = (int?) -2;
1002                 Assert (d2 > 1, false, "#2a");
1003                 d2 = (uint?) 44;
1004                 Assert (d2 > 44, false, "#2b");
1005
1006                 d = new MyType (30);
1007                 MyType? v3 = new MyType (30);
1008                 Assert (d > v3, false, "#3");
1009                 dynamic d3 = new MyType? (new MyType (-7));
1010                 Assert (d3 > new MyType (6), false, "#3a");
1011                 Assert (d3 > null, false, "#3b");
1012
1013                 d = 4.1m;
1014                 decimal? v4 = 4m;
1015                 Assert (d > v4, true, "#4");
1016                 v4 = null;
1017                 Assert (d > v4, false, "#4a");
1018         }
1019
1020         void GreaterThanEnumTest ()
1021         {
1022                 dynamic d = MyEnum.Value_1;
1023
1024                 Assert (d > null, false, "#1");
1025
1026                 Assert (d > MyEnum.Value_1, false, "#2");
1027                 Assert (d > 0, true, "#2a");
1028
1029                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1030                 Assert (d2 > MyEnumUlong.Value_2, false, "#3");
1031                 Assert (d2 > null, false, "#3a");
1032         }
1033
1034         void GreaterThanEqualTest ()
1035         {
1036                 dynamic d = 5;
1037
1038                 int v = 2;
1039                 Assert (d >= v, true, "#1");
1040                 double v2 = 5;
1041                 Assert (d >= v2, true, "#1a");
1042
1043                 d = 4.6;
1044                 Assert (d >= 4.59, true, "#2");
1045                 var b2 = 4.6;
1046                 Assert (d >= b2, true, "#2a");
1047
1048                 d = new MyType (30);
1049                 MyType v3 = new MyType (30);
1050                 Assert (d >= v3, true, "#3");
1051                 dynamic d3 = new MyType (-7);
1052                 Assert (d3 >= new MyType (6), false, "#3a");
1053
1054                 d3 = new MyTypeImplicitOnly (-7);
1055                 Assert (d3 >= 11, false, "#3b");
1056
1057                 d = 2m;
1058                 decimal v4 = 4m;
1059                 Assert (d >= v4, false, "#4");
1060                 Assert (d >= 2m, true, "#4a");
1061         }
1062
1063         void GreaterThanEqualNullableTest ()
1064         {
1065                 dynamic d = 5;
1066
1067                 int? v2 = null;
1068                 Assert (d >= v2, false, "#1");
1069                 Assert (d >= null, false, "#1a");
1070                 Assert (null >= d, false, "#1b");
1071
1072                 v2 = -2;
1073                 Assert (d >= v2, true, "#2");
1074                 dynamic d2 = (int?) -2;
1075                 Assert (d2 >= 1, false, "#2a");
1076                 d2 = (uint?) 44;
1077                 Assert (d2 >= 44, true, "#2b");
1078
1079                 d = new MyType (30);
1080                 MyType? v3 = new MyType (30);
1081                 Assert (d >= v3, true, "#3");
1082                 dynamic d3 = new MyType? (new MyType (-7));
1083                 Assert (d3 >= new MyType (6), false, "#3a");
1084                 Assert (d3 >= null, false, "#3b");
1085
1086                 d = 4.1m;
1087                 decimal? v4 = 4m;
1088                 Assert (d >= v4, true, "#4");
1089                 v4 = null;
1090                 Assert (d >= v4, false, "#4a");
1091         }
1092
1093         void GreaterThanEqualEnumTest ()
1094         {
1095                 dynamic d = MyEnum.Value_1;
1096
1097                 Assert (d >= null, false, "#1");
1098
1099                 Assert (d >= MyEnum.Value_1, true, "#2");
1100                 Assert (d >= 0, true, "#2a");
1101
1102                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1103                 Assert (d2 >= MyEnumUlong.Value_2, true, "#3");
1104                 Assert (d2 >= null, false, "#3a");
1105         }
1106
1107         void IsTest ()
1108         {
1109                 dynamic d = 1;
1110                 Assert (d is long, false, "#1");
1111                 Assert (d is int, true, "#2");
1112                 Assert (d is string, false, "#3");
1113         }
1114
1115         void LeftShiftTest ()
1116         {
1117                 dynamic d = (ulong) 0x7F000;
1118
1119                 int v = 2;
1120                 Assert<ulong> (d << v, 0x1FC000, "#1");
1121                 Assert<ulong> (d << 1, 0xFE000, "#1a");
1122                 short s = 2;
1123                 Assert<ulong> (d << s, 0x1FC000, "#1b");
1124
1125                 d = 0x7F000;
1126                 MyTypeImplicitOnly v3 = new MyTypeImplicitOnly (3);
1127                 Assert (d << v3, 0x3F8000, "#3");
1128                 dynamic d3 = new MyType (-7);
1129                 Assert (d3 << new MyTypeImplicitOnly (6), -448, "#3a");
1130                 Assert (d3 << 11, -14336, "#3b");
1131         }
1132
1133         void LeftShiftNullableTest ()
1134         {
1135                 dynamic d = 5;
1136
1137                 int? v2 = null;
1138                 Assert<int?> (d << v2, null, "#1");
1139                 d = 5;
1140                 Assert<int?> (d << null, null, "#1a");
1141                 d = 5;
1142                 Assert<int?> (null << d, null, "#1b");
1143
1144                 v2 = -2;
1145                 Assert (d << v2, 0x40000000, "#2");
1146                 dynamic d2 = (int?) -2;
1147                 Assert (d2 << 1, -4, "#2a");
1148
1149                 dynamic d3 = (int?) null;
1150                 Assert (d3 << (null << null), (int?)null, "#3");
1151         }
1152
1153         void LeftShiftAssignTest ()
1154         {
1155                 dynamic d = 0x7F000;
1156
1157                 int v = 2;
1158                 d <<= v;
1159                 Assert (d, 0x1FC000, "#1");
1160                 d <<= 1;
1161                 Assert (d, 0x3F8000, "#1a");
1162                 sbyte s = 2;
1163                 d <<= s;
1164                 Assert (d, 0xFE0000, "#1b");
1165         }
1166
1167         void LeftShiftAssignNullableTest ()
1168         {
1169                 dynamic d = 5;
1170
1171                 var v2 = -2;
1172                 d <<= v2;
1173                 Assert (d, 0x40000000, "#2");
1174                 dynamic d2 = (int?) -2;
1175                 d2 <<= 1;
1176                 Assert (d2, -4, "#2a");
1177         }
1178
1179         void LessThanTest ()
1180         {
1181                 dynamic d = 5;
1182
1183                 int v = 2;
1184                 Assert (d < v, false, "#1");
1185                 double v2 = 5;
1186                 Assert (d < v2, false, "#1a");
1187
1188                 d = 4.6;
1189                 Assert (d < 4.59, false, "#2");
1190                 var b2 = 4.6;
1191                 Assert (d < b2, false, "#2a");
1192
1193                 d = new MyType (30);
1194                 MyType v3 = new MyType (30);
1195                 Assert (d < v3, false, "#3");
1196                 dynamic d3 = new MyType (-7);
1197                 Assert (d3 < new MyType (6), true, "#3a");
1198
1199                 d3 = new MyTypeImplicitOnly (-7);
1200                 Assert (d3 < 11, true, "#3b");
1201
1202                 d = 2m;
1203                 decimal v4 = 4m;
1204                 Assert (d < v4, true, "#4");
1205                 Assert (d < 2m, false, "#4a");
1206         }
1207
1208         void LessThanNullableTest ()
1209         {
1210                 dynamic d = 5;
1211
1212                 int? v2 = null;
1213                 Assert (d < v2, false, "#1");
1214                 Assert (d < null, false, "#1a");
1215                 Assert (null < d, false, "#1b");
1216
1217                 v2 = -2;
1218                 Assert (d < v2, false, "#2");
1219                 dynamic d2 = (int?) -2;
1220                 Assert (d2 < 1, true, "#2a");
1221                 d2 = (uint?) 44;
1222                 Assert (d2 < 44, false, "#2b");
1223
1224                 d = new MyType (30);
1225                 MyType? v3 = new MyType (30);
1226                 Assert (d < v3, false, "#3");
1227                 dynamic d3 = new MyType? (new MyType (-7));
1228                 Assert (d3 < new MyType (6), true, "#3a");
1229
1230                 d3 = new MyTypeImplicitOnly (-7);
1231                 Assert (d3 < null, false, "#3b");
1232
1233                 d = 4.1m;
1234                 decimal? v4 = 4m;
1235                 Assert (d < v4, false, "#4");
1236                 v4 = null;
1237                 Assert (d < v4, false, "#4a");
1238         }
1239
1240         void LessThanEnumTest ()
1241         {
1242                 dynamic d = MyEnum.Value_1;
1243
1244                 Assert (d < null, false, "#1");
1245
1246                 Assert (d < MyEnum.Value_1, false, "#2");
1247                 Assert (d < 0, false, "#2a");
1248
1249                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1250                 Assert (d2 < MyEnumUlong.Value_2, false, "#3");
1251                 Assert (d2 < null, false, "#3a");
1252         }
1253
1254         void LessThanOrEqualTest ()
1255         {
1256                 dynamic d = 5;
1257
1258                 int v = 2;
1259                 Assert (d <= v, false, "#1");
1260                 double v2 = 5;
1261                 Assert (d <= v2, true, "#1a");
1262
1263                 d = 4.6;
1264                 Assert (d <= 4.59, false, "#2");
1265                 var b2 = 4.6;
1266                 Assert (d <= b2, true, "#2a");
1267
1268                 d = new MyType (30);
1269                 MyType v3 = new MyType (30);
1270                 Assert (d <= v3, true, "#3");
1271                 dynamic d3 = new MyType (-7);
1272                 Assert (d3 <= new MyType (6), true, "#3a");
1273
1274                 d3 = new MyTypeImplicitOnly (-7);
1275                 Assert (d3 <= 11, true, "#3b");
1276
1277                 d = 2m;
1278                 decimal v4 = 4m;
1279                 Assert (d <= v4, true, "#4");
1280                 Assert (d <= 2m, true, "#4a");
1281         }
1282
1283         void LessThanOrEqualNullableTest ()
1284         {
1285                 dynamic d = 5;
1286
1287                 int? v2 = null;
1288                 Assert (d <= v2, false, "#1");
1289                 Assert (d <= null, false, "#1a");
1290                 Assert (null <= d, false, "#1b");
1291
1292                 v2 = -2;
1293                 Assert (d <= v2, false, "#2");
1294                 dynamic d2 = (int?) -2;
1295                 Assert (d2 <= 1, true, "#2a");
1296                 d2 = (uint?) 44;
1297                 Assert (d2 <= 44, true, "#2b");
1298
1299                 d = new MyType (30);
1300                 MyType? v3 = new MyType (30);
1301                 Assert (d <= v3, true, "#3");
1302                 dynamic d3 = new MyType? (new MyType (-7));
1303                 Assert (d3 <= new MyType (6), true, "#3a");
1304                 Assert (d3 <= null, false, "#3b");
1305
1306                 d = 4.1m;
1307                 decimal? v4 = 4m;
1308                 Assert (d <= v4, false, "#4");
1309                 v4 = null;
1310                 Assert (d <= v4, false, "#4a");
1311         }
1312
1313         void LessThanOrEqualEnumTest ()
1314         {
1315                 dynamic d = MyEnum.Value_1;
1316
1317                 Assert (d <= null, false, "#1");
1318
1319                 Assert (d <= MyEnum.Value_1, true, "#2");
1320                 Assert (d <= 0, false, "#2a");
1321
1322                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1323                 Assert (d2 <= MyEnumUlong.Value_2, true, "#3");
1324                 Assert (d2 <= null, false, "#3a");
1325         }
1326
1327         void ModuloTest ()
1328         {
1329                 dynamic d = 5;
1330
1331                 int v = 2;
1332                 Assert (d % v, 1, "#1");
1333
1334                 d = new MyType (5);
1335                 MyType v3 = new MyType (30);
1336                 Assert (d % v3, new MyType (5), "#3");
1337                 dynamic d3 = new MyType (-7);
1338                 Assert<MyType> (d3 % new MyType (6), new MyType (-1), "#3a");
1339
1340                 d = new MyTypeImplicitOnly (5);
1341                 decimal v4 = 4m;
1342                 Assert (d % v4, 1m, "#4");
1343         }
1344
1345         void ModuloNullableTest ()
1346         {
1347                 dynamic d = 5;
1348
1349                 double? v2 = null;
1350                 Assert<double?> (d % v2, null, "#1");
1351                 Assert<double?> (d % null, null, "#1a");
1352                 Assert<double?> (null % d, null, "#1b");
1353
1354                 v2 = -2;
1355                 Assert (d % v2, 1, "#2");
1356                 dynamic d2 = (int?) -2;
1357                 Assert (d2 % 1, 0, "#2a");
1358
1359                 d = new MyType (-2);
1360                 MyType? v3 = new MyType (30);
1361                 Assert (d % v3, new MyType (-2), "#3");
1362                 dynamic d3 = new MyType? (new MyType (-7));
1363                 Assert (d3 % new MyType (6), new MyType (-1), "#3a");
1364                 Assert<MyType?> (d3 + null, null, "#3b");
1365
1366                 d = new MyTypeImplicitOnly (5);
1367                 decimal? v4 = 4m;
1368                 Assert (d % v4, 1m, "#4");
1369                 v4 = null;
1370                 Assert<decimal?> (d % v4, null, "#4a");
1371         }
1372
1373         void ModuloAssignTest ()
1374         {
1375                 dynamic d = 5;
1376
1377                 int v = 2;
1378                 d %= v;
1379                 Assert (d, 1, "#1");
1380
1381                 d = 5.0;
1382                 double v2 = 0.5;
1383                 d %= v2;
1384                 Assert (d, 0, "#1a");
1385                 d %= v;
1386                 Assert (d, 0, "#1b");
1387
1388                 dynamic d3 = new MyType (-7);
1389                 d3 %= new MyType (6);
1390                 Assert<MyType> (d3, new MyType (-1), "#3");
1391
1392                 d = 5m;
1393                 decimal v4 = 4m;
1394                 d %= v4;
1395                 Assert (d, 1m, "#4");
1396         }
1397
1398         void MultiplyTest ()
1399         {
1400                 dynamic d = 5;
1401
1402                 int v = 2;
1403                 Assert (d * v, 10, "#1");
1404                 double v2 = 0.5;
1405                 Assert (d * v2, 2.5, "#1a");
1406
1407                 d = new MyType (5);
1408                 MyType v3 = new MyType (30);
1409                 Assert (d * v3, new MyType (150), "#3");
1410                 dynamic d3 = new MyType (-7);
1411                 Assert<MyType> (d3 * new MyType (6), new MyType (-42), "#3a");
1412
1413                 decimal v4 = 4m;
1414                 d = 7.9m;
1415                 Assert (d * v4, 31.6m, "#4");
1416         }
1417
1418         void MultiplyNullableTest ()
1419         {
1420                 dynamic d = 5;
1421
1422                 int? v2 = null;
1423                 Assert<int?> (d * v2, null, "#1");
1424                 Assert<int?> (d * null, null, "#1a");
1425                 Assert<int?> (null * d, null, "#1b");
1426
1427                 v2 = -2;
1428                 Assert (d * v2, -10, "#2");
1429                 dynamic d2 = (int?) -2;
1430                 Assert (d2 * 1, -2, "#2a");
1431
1432                 d = new MyType (5);
1433                 MyType? v3 = new MyType (30);
1434                 Assert (d * v3, new MyType (150), "#3");
1435                 dynamic d3 = new MyType? (new MyType (-7));
1436                 Assert (d3 * new MyType (6), new MyType (-42), "#3a");
1437                 Assert<MyType?> (d3 * null, null, "#3b");
1438
1439                 d = new MyTypeImplicitOnly (5);
1440                 decimal? v4 = 4m;
1441                 Assert (d * v4, 20m, "#4");
1442                 v4 = null;
1443                 Assert<decimal?> (d * v4, null, "#4a");
1444         }
1445
1446         void MultiplyCheckedTest ()
1447         {
1448                 checked {
1449                         dynamic d = 5;
1450
1451                         int v = int.MaxValue;
1452                         AssertChecked (() => d * v, 7, "#1");
1453
1454                         int? v2 = v;
1455                         AssertChecked (() => d * v2, null, "#2");
1456
1457                         d = new MyType (4);
1458                         MyType v3 = new MyType (int.MaxValue);
1459                         Assert (d * v3, new MyType (-4), "#3");
1460                 }
1461         }
1462
1463         void MultiplyAssignTest ()
1464         {
1465                 dynamic d = 5;
1466
1467                 int v = 2;
1468                 d *= v;
1469                 Assert (d, 10, "#1");
1470
1471                 d = 5.0;
1472                 double v2 = 0.5;
1473                 d *= v2;
1474                 Assert (d, 2.5, "#1a");
1475                 d *= v;
1476                 Assert (d, 5, "#1b");
1477
1478                 dynamic d3 = new MyType (-7);
1479                 d3 *= new MyType (6);
1480                 Assert<MyType> (d3, new MyType (-42), "#3");
1481
1482                 d = 5m;
1483                 decimal v4 = 4m;
1484                 d *= v4;
1485                 Assert (d, 20m, "#4");
1486                 
1487                 int i = 3;
1488                 d = 5;
1489                 i *= d;
1490                 Assert (i, 15, "#5");
1491         }
1492
1493         void MultiplyAssignCheckedTest ()
1494         {
1495                 checked {
1496                         dynamic d = 5;
1497
1498                         int v = int.MaxValue;
1499                         AssertChecked (() => { d *= v; Assert (d, 0, "#1-"); }, "#1");
1500
1501                         d = new MyType (44);
1502                         MyType v3 = new MyType (int.MaxValue);
1503                         d *= v3;
1504                         Assert (d, new MyType (-44), "#3-");
1505                 }
1506         }
1507
1508         void Negate ()
1509         {
1510                 dynamic d = -8;
1511                 Assert (8, -d, "#1");
1512                 Assert (-8, -(-d), "#1a");
1513
1514                 d = new MyType (-14);
1515                 Assert (new MyType (14), -d, "#2");
1516
1517                 d = new MyTypeImplicitOnly (4);
1518                 Assert (-4, -d, "#3");
1519
1520                 d = (uint) 7;
1521                 Assert (-7, -d, "#4");
1522
1523                 d = double.NegativeInfinity;
1524                 Assert (double.PositiveInfinity, -d, "#5");
1525         }
1526
1527         void NegateNullable ()
1528         {
1529                 dynamic d = (int?) -8;
1530                 Assert (8, -d, "#1");
1531                 Assert (-8, -(-d), "#1a");
1532
1533                 MyType? n1 = new MyType (4);
1534                 d = n1;
1535                 Assert (new MyType (-4), -d, "#2");
1536
1537                 MyTypeImplicitOnly? n2 = new MyTypeImplicitOnly (4);
1538                 d = n2;
1539                 Assert (-4, -d, "#3");
1540
1541                 d = (sbyte?) 7;
1542                 Assert (-7, -d, "#4");
1543         }
1544
1545         void NegateChecked ()
1546         {
1547                 checked {
1548                         dynamic d = int.MinValue;
1549                         AssertChecked (() => -d, 0, "#1");
1550                 }
1551         }
1552
1553         void Not ()
1554         {
1555                 dynamic d = true;
1556                 Assert (false, !d, "#1");
1557
1558                 var de = new MyType (-1);
1559                 Assert (false, !d, "#2");
1560         }
1561
1562         void NotEqualTest ()
1563         {
1564                 dynamic d = 5;
1565
1566                 int v = 2;
1567                 Assert (d != v, true, "#1");
1568                 double v2 = 5;
1569                 Assert (d != v2, false, "#1a");
1570
1571                 d = true;
1572                 Assert (d != false, true, "#2");
1573                 bool b2 = true;
1574                 Assert (d != b2, false, "#2a");
1575
1576                 d = new MyType (30);
1577                 MyType v3 = new MyType (30);
1578                 Assert (d != v3, false, "#3");
1579                 dynamic d3 = new MyType (-7);
1580                 Assert (d3 != new MyType (6), true, "#3a");
1581
1582                 d = 2m;
1583                 decimal v4 = 4m;
1584                 Assert (d != v4, true, "#4");
1585                 Assert (d != 2m, false, "#4a");
1586
1587                 d = null;
1588                 Assert (d != null, false, "#5");
1589         }
1590
1591         void NotEqualNullableTest ()
1592         {
1593                 dynamic d = 5;
1594
1595                 int? v2 = null;
1596                 Assert (d != v2, true, "#1");
1597                 Assert (d != null, true, "#1a");
1598                 Assert (null != d, true, "#1b");
1599
1600                 v2 = -2;
1601                 Assert (d != v2, true, "#2");
1602                 dynamic d2 = (int?) -2;
1603                 Assert (d2 != 1, true, "#2a");
1604                 d2 = (uint?) 44;
1605                 Assert (d2 != 44, false, "#2b");
1606
1607                 d = new MyType (30);
1608                 MyType? v3 = new MyType (30);
1609                 Assert (d != v3, false, "#3");
1610                 dynamic d3 = new MyType? (new MyType (-7));
1611                 Assert (d3 != new MyType (6), true, "#3a");
1612                 Assert (d3 != null, true, "#3b");
1613
1614                 d = 4.1m;
1615                 decimal? v4 = 4m;
1616                 Assert (d != v4, true, "#4");
1617                 v4 = null;
1618                 Assert (d != v4, true, "#4a");
1619
1620                 d = (bool?) true;
1621                 Assert (d != true, false, "#5");
1622                 Assert (d != null, true, "#5a");
1623                 Assert (d != false, true, "#5b");
1624
1625                 d = null;
1626                 long? l = null;
1627                 Assert (d != l, false, "#6a");
1628                 Assert (l != d, false, "#6b");
1629         }
1630
1631         void NotEqualEnumTest ()
1632         {
1633                 dynamic d = MyEnum.Value_1;
1634
1635                 Assert (d != null, true, "#1");
1636
1637                 Assert (d != MyEnum.Value_1, false, "#2");
1638                 Assert (d != 0, true, "#2a");
1639
1640                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1641                 Assert (d2 != MyEnumUlong.Value_2, false, "#3");
1642                 Assert (d2 != null, true, "#3a");
1643         }
1644
1645         void NotEqualStringTest ()
1646         {
1647                 dynamic d = "text";
1648
1649                 Assert (d != "te", true, "#1");
1650                 Assert (d != "text", false, "#1a");
1651                 Assert (d != null, true, "#1b");
1652         }
1653
1654         void OnesComplement ()
1655         {
1656                 dynamic d = 7;
1657                 Assert (-8, ~d, "#1");
1658
1659                 d = new MyType (-1);
1660                 Assert (0, ~d, "#2");
1661
1662                 d = (ulong) 7;
1663                 Assert (18446744073709551608, ~d, "#3");
1664
1665                 d = MyEnum.Value_1;
1666                 Assert ((MyEnum) 254, ~d, "#4");
1667         }
1668
1669         void OnesComplementNullable ()
1670         {
1671                 dynamic d = (int?) 7;
1672                 Assert (-8, ~d, "#1");
1673
1674                 d = (MyEnum?) MyEnum.Value_1;
1675                 Assert ((MyEnum) 254, ~d, "#4");
1676         }
1677
1678         void OrTest ()
1679         {
1680                 dynamic d = true;
1681
1682                 var v = false;
1683                 Assert (d | v, true, "#1");
1684                 Assert (d | false, true, "#1a");
1685
1686                 d = 42;
1687                 var v2 = 62;
1688                 Assert (d | v2, 62, "#2");
1689                 Assert (d | 0, 42, "#2a");
1690
1691                 d = new MyType (42);
1692                 MyType v3 = new MyType (30);
1693                 Assert (d | v3, new MyType (62), "#3");
1694                 dynamic d3 = new MyType (-7);
1695                 Assert<MyType> (d3 | new MyType (6), new MyType (-1), "#3a");
1696
1697                 d3 = new MyTypeImplicitOnly (-7);
1698                 Assert (d3 | 11, -5, "#3b");
1699         }
1700
1701         void OrTestEnum ()
1702         {
1703                 dynamic d = MyEnum.Value_1;
1704
1705                 Assert<MyEnum?> (d | null, null, "#1");
1706
1707                 Assert (d | d, MyEnum.Value_1, "#2");
1708
1709                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
1710                 Assert<MyEnumUlong> (d2 | MyEnumUlong.Value_2, (MyEnumUlong) 3, "#3");
1711         }
1712
1713         void OrTestNullable ()
1714         {
1715                 dynamic d = 5;
1716
1717                 int? v2 = null;
1718                 Assert<int?> (d | v2, null, "#1");
1719                 Assert<int?> (d | null, null, "#1a");
1720                 Assert<int?> (null | d, null, "#1b");
1721
1722                 v2 = -2;
1723                 Assert (d | v2, -1, "#2");
1724                 dynamic d2 = (int?) -2;
1725                 Assert (d2 | 1, -1, "#2a");
1726
1727                 d = new MyType (-2);
1728                 MyType? v3 = new MyType (30);
1729                 Assert (d | v3, new MyType (-2), "#3");
1730                 dynamic d3 = new MyType? (new MyType (-7));
1731                 Assert (d3 | new MyType (6), new MyType (-1), "#3a");
1732         }
1733
1734         void OrAssignedTest ()
1735         {
1736                 dynamic d = true;
1737
1738                 var v = false;
1739                 d |= v;
1740                 Assert (d, true, "#1");
1741                 d = true;
1742                 d |= true;
1743                 Assert (d, true, "#1a");
1744
1745                 d = 42;
1746                 var v2 = 62;
1747                 d |= v2;
1748                 Assert (d, 62, "#2");
1749
1750                 MyType v3 = new MyType (30);
1751                 dynamic d3 = new MyType (-7);
1752                 d3 |= new MyType (6);
1753                 Assert<MyType> (d3, new MyType (-1), "#3");
1754         }
1755
1756         void OrAssignedTestEnum ()
1757         {
1758                 dynamic d = MyEnum.Value_1;
1759                 d |= MyEnum.Value_2;
1760                 Assert<MyEnum> (d, (MyEnum) 3, "#1");
1761
1762                 d = MyEnum.Value_2;
1763                 d |= d;
1764                 Assert (d, MyEnum.Value_2, "#2");
1765
1766                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
1767                 Assert<MyEnumUlong> (d2 | MyEnumUlong.Value_2, (MyEnumUlong)3, "#3");
1768         }
1769
1770         void OrElseTest ()
1771         {
1772                 dynamic d = true;
1773
1774                 var v = false;
1775                 Assert<bool> (d || v, true, "#1");
1776
1777                 Assert (d || true, true, "#1a");
1778
1779                 d = true;
1780                 Assert (d || d, true, "#2");
1781
1782                 dynamic d3 = new MyType (-7);
1783                 Assert<MyType> (d3 || new MyType (6), new MyType (-7), "#3");
1784         }
1785
1786         void RightShiftTest ()
1787         {
1788                 dynamic d = (ulong) 0x7F000;
1789
1790                 int v = 2;
1791                 Assert<ulong> (d >> v, 0x1FC00, "#1");
1792                 Assert<ulong> (d >> 1, 0x3F800, "#1a");
1793                 short s = 2;
1794                 Assert<ulong> (d >> s, 0x1FC00, "#1b");
1795
1796                 d = 0x7F000;
1797                 MyTypeImplicitOnly v3 = new MyTypeImplicitOnly (3);
1798                 Assert (d >> v3, 0xFE00, "#3");
1799                 dynamic d3 = new MyType (-7);
1800                 Assert (d3 >> new MyTypeImplicitOnly (11), -1, "#3a");
1801         }
1802
1803         void RightShiftNullableTest ()
1804         {
1805                 dynamic d = 5;
1806
1807                 int? v2 = null;
1808                 Assert<int?> (d >> v2, null, "#1");
1809                 d = 5;
1810                 Assert<int?> (d >> null, null, "#1a");
1811                 d = 5;
1812                 Assert<int?> (null >> d, null, "#1b");
1813
1814                 v2 = -2;
1815                 Assert (d >> v2, 0, "#2");
1816                 dynamic d2 = (int?) -200;
1817                 Assert (d2 >> 1, -100, "#2a");
1818
1819                 dynamic d3 = (int?) null;
1820                 Assert (d3 >> (null >> null), (int?) null, "#3");
1821         }
1822
1823         void RightShiftAssignTest ()
1824         {
1825                 dynamic d = 0x7F000;
1826
1827                 int v = 2;
1828                 d >>= v;
1829                 Assert (d, 0x1FC00, "#1");
1830                 d >>= 1;
1831                 Assert (d, 0xFE00, "#1a");
1832                 sbyte s = 2;
1833                 d >>= s;
1834                 Assert (d, 0x3F80, "#1b");
1835         }
1836
1837         void RightShiftAssignNullableTest ()
1838         {
1839                 dynamic d = 0x2A0;
1840
1841                 var v2 = -2;
1842                 d >>= v2;
1843                 Assert (d, 0, "#2");
1844                 dynamic d2 = (int?) -2;
1845                 d2 >>= 1;
1846                 Assert (d2, -1, "#2a");
1847         }
1848
1849         void SubtractTest ()
1850         {
1851                 dynamic d = 5;
1852
1853                 int v = 2;
1854                 Assert (d - v, 3, "#1");
1855                 double v2 = 0.5;
1856                 Assert (d - v2, 4.5, "#1a");
1857
1858                 d = new MyType (5);
1859                 MyType v3 = new MyType (30);
1860                 Assert (d - v3, new MyType (-25), "#3");
1861                 dynamic d3 = new MyType (-7);
1862                 Assert (d3 - new MyType (6), new MyType (-13), "#3a");
1863
1864                 d = new MyTypeImplicitOnly (5);
1865                 decimal v4 = 4m;
1866                 Assert (d - v4, 1m, "#4");
1867         }
1868
1869         void SubtractNullableTest ()
1870         {
1871                 dynamic d = 5;
1872
1873                 int? v2 = null;
1874                 Assert<int?> (d - v2, null, "#1");
1875                 Assert<int?> (d - null, null, "#1a");
1876                 Assert<int?> (null - d, null, "#1b");
1877
1878                 v2 = -2;
1879                 Assert (d - v2, 7, "#2");
1880                 dynamic d2 = (int?) -2;
1881                 Assert (d2 - 1, -3, "#2a");
1882
1883                 d = new MyType (5);
1884                 MyType? v3 = new MyType (30);
1885                 Assert (d - v3, new MyType (-25), "#3");
1886                 dynamic d3 = new MyType? (new MyType (-7));
1887                 Assert (d3 - new MyType (6), new MyType (-13), "#3a");
1888                 Assert<MyType?> (d3 - null, null, "#3b");
1889
1890                 d = new MyTypeImplicitOnly (5);
1891                 decimal? v4 = 4m;
1892                 Assert (d - v4, 1m, "#4");
1893                 v4 = null;
1894                 Assert<decimal?> (d - v4, null, "#4a");
1895         }
1896
1897         void SubtractEnumTest ()
1898         {
1899                 dynamic d = MyEnum.Value_1;
1900
1901                 Assert<MyEnum> (d - 1, 0, "#1");
1902
1903                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1904                 Assert (d2 - (byte) 1, MyEnumUlong.Value_1, "#2");
1905                 Assert<MyEnumUlong?> (d2 - null, null, "#2a");
1906                 
1907                 // CSC: Invalid System.InvalidOperationException
1908                 Assert<MyEnum?> (d - null, null, "#3");
1909         }
1910
1911         void SubtractCheckedTest ()
1912         {
1913                 checked {
1914                         dynamic d = 5;
1915
1916                         int v = int.MinValue;
1917                         AssertChecked (() => d - v, 7, "#1");
1918
1919                         int? v2 = v;
1920                         AssertChecked (() => d - v2, null, "#2");
1921
1922                         d = new MyType (5);
1923                         MyType v3 = new MyType (int.MinValue);
1924                         Assert (d - v3, new MyType (-2147483643), "#3");
1925                 }
1926         }
1927
1928         void SubtractAssignTest ()
1929         {
1930                 dynamic d = 5;
1931
1932                 int v = 2;
1933                 d -= v;
1934                 Assert (d, 3, "#1");
1935
1936                 d = 5.0;
1937                 double v2 = 0.5;
1938                 d -= v2;
1939                 Assert (d, 4.5, "#1a");
1940                 d -= v;
1941                 Assert (d, 2.5, "#1b");
1942
1943                 dynamic d3 = new MyType (-7);
1944                 d3 -= new MyType (6);
1945                 Assert<MyType> (d3, new MyType (-13), "#3");
1946
1947                 d = 5m;
1948                 decimal v4 = 4m;
1949                 d -= v4;
1950                 Assert (d, 1m, "#4");
1951         }
1952
1953         void SubtractAssignEnumTest ()
1954         {
1955                 dynamic d = MyEnum.Value_1;
1956
1957                 d -= 1;
1958                 Assert<MyEnum> (d, 0, "#2");
1959
1960                 dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
1961                 d2 -= (byte) 1;
1962                 Assert (d2, MyEnumUlong.Value_1, "#3");
1963         }
1964
1965         void SubtractAssignCheckedTest ()
1966         {
1967                 checked {
1968                         dynamic d = 5;
1969
1970                         int v = int.MinValue;
1971                         AssertChecked (() => { d -= v; Assert (d, 0, "#1a"); }, "#1");
1972
1973                         d = new MyType (5);
1974                         MyType v3 = new MyType (int.MinValue);
1975                         d -= v3;
1976                         Assert (d, new MyType (-2147483643), "#3a");
1977                 }
1978         }
1979
1980         void SubtractAssignEvent ()
1981         {
1982                 Action print = () => { Console.WriteLine ("foo"); };
1983                 dynamic d = print;
1984                 
1985                 // FIXME: Will have to special case events
1986                 //ev_assign -= d;
1987                 //ev_assign ();
1988         }
1989
1990         void UnaryDecrement ()
1991         {
1992                 dynamic d = 3;
1993                 Assert (3, d--, "#1");
1994                 Assert (2, d, "#1a");
1995
1996                 d = 3;
1997                 Assert (2, --d, "#2");
1998                 Assert (2, d, "#2a");
1999
2000                 d = new MyType (-3);
2001                 Assert (new MyType (-3), d--, "#3");
2002                 Assert (new MyType (-1), d, "#3a");
2003         }
2004
2005         void UnaryDecrementCheckedTest ()
2006         {
2007                 checked {
2008                         dynamic d = int.MinValue;
2009
2010                         AssertChecked (() => { d--; Assert (d, -1073741824, "#1a"); }, "#1");
2011
2012                         d = new MyType (int.MinValue);
2013                         d--;
2014                         Assert (d, new MyType (-1073741824), "#2");
2015                 }
2016         }
2017
2018         void UnaryIncrement ()
2019         {
2020                 dynamic d = 3;
2021                 Assert (3, d++, "#1");
2022                 Assert (4, d, "#1a");
2023
2024                 d = 3;
2025                 Assert (4, ++d, "#2");
2026                 Assert (4, d, "#2a");
2027
2028                 d = new MyType (-3);
2029                 Assert (new MyType (-3), d++, "#3");
2030                 Assert (new MyType (-6), d, "#3a");
2031         }
2032
2033         void UnaryIncrementCheckedTest ()
2034         {
2035                 checked {
2036                         dynamic d = int.MaxValue;
2037
2038                         AssertChecked (() => { d++; Assert (d, 0, "#1a"); }, "#1");
2039
2040                         d = new MyType (int.MaxValue);
2041                         d++;
2042                         Assert (d, new MyType (-2), "#2");
2043                 }
2044         }
2045
2046         //void UnaryIsFalse ()
2047         //{
2048         //    dynamic d = this;
2049         //    object r = d == null;
2050         //    Assert (false, (bool) r, "#1");
2051         //    Assert<object> (true, d != null, "#1a");
2052         //}
2053
2054         void UnaryIsTrue ()
2055         {
2056                 dynamic d = true;
2057                 Assert (3, d ? 3 : 5, "#1");
2058
2059                 d = 4;
2060                 Assert (false, d < 1, "#2");
2061
2062                 d = new InverseLogicalOperator (true);
2063                 Assert (1, d ? 1 : -1, "#3");
2064         }
2065
2066         void UnaryPlus ()
2067         {
2068                 dynamic d = -8;
2069                 Assert (-8, +d, "#1");
2070                 Assert (-8, +(+d), "#1a");
2071
2072                 d = new MyType (14);
2073                 Assert (new MyType (334455), +d, "#2");
2074
2075                 d = new MyTypeImplicitOnly (4);
2076                 Assert (4, +d, "#3");
2077
2078                 d = (uint) 7;
2079                 Assert<uint> (7, +d, "#4");
2080         }
2081
2082         void UnaryPlusNullable ()
2083         {
2084                 dynamic d = (int?) -8;
2085                 Assert (-8, +d, "#1");
2086                 Assert (-8, +(+d), "#1a");
2087
2088                 MyType? n1 = new MyType (4);
2089                 d = n1;
2090                 Assert (new MyType (334455), +d, "#2");
2091
2092                 MyTypeImplicitOnly? n2 = new MyTypeImplicitOnly (4);
2093                 d = n2;
2094                 Assert (4, +d, "#3");
2095
2096                 d = (sbyte?) 7;
2097                 Assert (7, +d, "#4");
2098         }
2099
2100 #pragma warning restore 169
2101
2102         static bool RunTest (MethodInfo test)
2103         {
2104                 Console.Write ("Running test {0, -25}", test.Name);
2105                 try {
2106                         test.Invoke (new Tester (), null);
2107                         Console.WriteLine ("OK");
2108                         return true;
2109                 } catch (Exception e) {
2110                         Console.WriteLine ("FAILED");
2111                         Console.WriteLine (e.ToString ());
2112                         return false;
2113                 }
2114         }
2115
2116         public static int Main ()
2117         {
2118                 var tests = from test in typeof (Tester).GetMethods (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
2119                                         where test.GetParameters ().Length == 0
2120                                         orderby test.Name
2121                                         select RunTest (test);
2122
2123                 int failures = tests.Count (a => !a);
2124                 Console.WriteLine (failures + " tests failed");
2125                 return failures;
2126         }
2127 }
2128