83f0f3ef14fbf0fc5ea1ccdb19878f4923082e86
[platform/upstream/gcc.git] / gcc / d / dmd / constfold.c
1
2 /* Compiler implementation of the D programming language
3  * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
4  * written by Walter Bright
5  * http://www.digitalmars.com
6  * Distributed under the Boost Software License, Version 1.0.
7  * http://www.boost.org/LICENSE_1_0.txt
8  * https://github.com/D-Programming-Language/dmd/blob/master/src/constfold.c
9  */
10
11 #include "root/dsystem.h"               // mem{cpy|set|cmp}()
12
13 #ifndef IN_GCC
14 #include <math.h>
15 #endif
16
17 #include "root/rmem.h"
18 #include "root/root.h"
19 #include "root/port.h"
20
21 #include "errors.h"
22 #include "mtype.h"
23 #include "expression.h"
24 #include "aggregate.h"
25 #include "declaration.h"
26 #include "utf.h"
27 #include "ctfe.h"
28 #include "target.h"
29
30 int RealEquals(real_t x1, real_t x2);
31
32 Expression *expType(Type *type, Expression *e)
33 {
34     if (type != e->type)
35     {
36         e = e->copy();
37         e->type = type;
38     }
39     return e;
40 }
41
42 /* ================================== isConst() ============================== */
43
44 int isConst(Expression *e)
45 {
46     //printf("Expression::isConst(): %s\n", e->toChars());
47     switch (e->op)
48     {
49         case TOKint64:
50         case TOKfloat64:
51         case TOKcomplex80:
52             return 1;
53         case TOKnull:
54             return 0;
55         case TOKsymoff:
56             return 2;
57         default:
58             return 0;
59     }
60     assert(0);
61     return 0;
62 }
63
64 /* =============================== constFold() ============================== */
65
66 /* The constFold() functions were redundant with the optimize() ones,
67  * and so have been folded in with them.
68  */
69
70 /* ========================================================================== */
71
72 UnionExp Neg(Type *type, Expression *e1)
73 {
74     UnionExp ue;
75     Loc loc = e1->loc;
76
77     if (e1->type->isreal())
78     {
79         new(&ue) RealExp(loc, -e1->toReal(), type);
80     }
81     else if (e1->type->isimaginary())
82     {
83         new(&ue) RealExp(loc, -e1->toImaginary(), type);
84     }
85     else if (e1->type->iscomplex())
86     {
87         new(&ue) ComplexExp(loc, -e1->toComplex(), type);
88     }
89     else
90     {
91         new(&ue) IntegerExp(loc, -e1->toInteger(), type);
92     }
93     return ue;
94 }
95
96 UnionExp Com(Type *type, Expression *e1)
97 {
98     UnionExp ue;
99     Loc loc = e1->loc;
100
101     new(&ue) IntegerExp(loc, ~e1->toInteger(), type);
102     return ue;
103 }
104
105 UnionExp Not(Type *type, Expression *e1)
106 {
107     UnionExp ue;
108     Loc loc = e1->loc;
109
110     new(&ue) IntegerExp(loc, e1->isBool(false) ? 1 : 0, type);
111     return ue;
112 }
113
114 UnionExp Bool(Type *type, Expression *e1)
115 {
116     UnionExp ue;
117     Loc loc = e1->loc;
118
119     new(&ue) IntegerExp(loc, e1->isBool(true) ? 1 : 0, type);
120     return ue;
121 }
122
123 UnionExp Add(Loc loc, Type *type, Expression *e1, Expression *e2)
124 {
125     UnionExp ue;
126
127     if (type->isreal())
128     {
129         new(&ue) RealExp(loc, e1->toReal() + e2->toReal(), type);
130     }
131     else if (type->isimaginary())
132     {
133         new(&ue) RealExp(loc, e1->toImaginary() + e2->toImaginary(), type);
134     }
135     else if (type->iscomplex())
136     {
137         // This rigamarole is necessary so that -0.0 doesn't get
138         // converted to +0.0 by doing an extraneous add with +0.0
139         complex_t c1 = complex_t(CTFloat::zero);
140         real_t r1 = CTFloat::zero;
141         real_t i1 = CTFloat::zero;
142
143         complex_t c2 = complex_t(CTFloat::zero);
144         real_t r2 = CTFloat::zero;
145         real_t i2 = CTFloat::zero;
146
147         complex_t v = complex_t(CTFloat::zero);
148         int x;
149
150         if (e1->type->isreal())
151         {
152             r1 = e1->toReal();
153             x = 0;
154         }
155         else if (e1->type->isimaginary())
156         {
157             i1 = e1->toImaginary();
158             x = 3;
159         }
160         else
161         {
162             c1 = e1->toComplex();
163             x = 6;
164         }
165
166         if (e2->type->isreal())
167         {
168             r2 = e2->toReal();
169         }
170         else if (e2->type->isimaginary())
171         {
172             i2 = e2->toImaginary();
173             x += 1;
174         }
175         else
176         {
177             c2 = e2->toComplex();
178             x += 2;
179         }
180
181         switch (x)
182         {
183         case 0 + 0:
184             v = complex_t(r1 + r2);
185             break;
186         case 0 + 1:
187             v = complex_t(r1, i2);
188             break;
189         case 0 + 2:
190             v = complex_t(r1 + creall(c2), cimagl(c2));
191             break;
192         case 3 + 0:
193             v = complex_t(r2, i1);
194             break;
195         case 3 + 1:
196             v = complex_t(CTFloat::zero, i1 + i2);
197             break;
198         case 3 + 2:
199             v = complex_t(creall(c2), i1 + cimagl(c2));
200             break;
201         case 6 + 0:
202             v = complex_t(creall(c1) + r2, cimagl(c2));
203             break;
204         case 6 + 1:
205             v = complex_t(creall(c1), cimagl(c1) + i2);
206             break;
207         case 6 + 2:
208             v = c1 + c2;
209             break;
210         default:
211             assert(0);
212         }
213         new(&ue) ComplexExp(loc, v, type);
214     }
215     else if (e1->op == TOKsymoff)
216     {
217         SymOffExp *soe = (SymOffExp *)e1;
218         new(&ue) SymOffExp(loc, soe->var, soe->offset + e2->toInteger());
219         ue.exp()->type = type;
220     }
221     else if (e2->op == TOKsymoff)
222     {
223         SymOffExp *soe = (SymOffExp *)e2;
224         new(&ue) SymOffExp(loc, soe->var, soe->offset + e1->toInteger());
225         ue.exp()->type = type;
226     }
227     else
228         new(&ue) IntegerExp(loc, e1->toInteger() + e2->toInteger(), type);
229     return ue;
230 }
231
232
233 UnionExp Min(Loc loc, Type *type, Expression *e1, Expression *e2)
234 {
235     UnionExp ue;
236
237     if (type->isreal())
238     {
239         new(&ue) RealExp(loc, e1->toReal() - e2->toReal(), type);
240     }
241     else if (type->isimaginary())
242     {
243         new(&ue) RealExp(loc, e1->toImaginary() - e2->toImaginary(), type);
244     }
245     else if (type->iscomplex())
246     {
247         // This rigamarole is necessary so that -0.0 doesn't get
248         // converted to +0.0 by doing an extraneous add with +0.0
249         complex_t c1 = complex_t(CTFloat::zero);
250         real_t r1 = CTFloat::zero;
251         real_t i1 = CTFloat::zero;
252
253         complex_t c2 = complex_t(CTFloat::zero);
254         real_t r2 = CTFloat::zero;
255         real_t i2 = CTFloat::zero;
256
257         complex_t v = complex_t(CTFloat::zero);
258         int x;
259
260         if (e1->type->isreal())
261         {
262             r1 = e1->toReal();
263             x = 0;
264         }
265         else if (e1->type->isimaginary())
266         {
267             i1 = e1->toImaginary();
268             x = 3;
269         }
270         else
271         {
272             c1 = e1->toComplex();
273             x = 6;
274         }
275
276         if (e2->type->isreal())
277         {
278             r2 = e2->toReal();
279         }
280         else if (e2->type->isimaginary())
281         {
282             i2 = e2->toImaginary();
283             x += 1;
284         }
285         else
286         {
287             c2 = e2->toComplex();
288             x += 2;
289         }
290
291         switch (x)
292         {
293         case 0 + 0:
294             v = complex_t(r1 - r2);
295             break;
296         case 0 + 1:
297             v = complex_t(r1, -i2);
298             break;
299         case 0 + 2:
300             v = complex_t(r1 - creall(c2), -cimagl(c2));
301             break;
302         case 3 + 0:
303             v = complex_t(-r2, i1);
304             break;
305         case 3 + 1:
306             v = complex_t(CTFloat::zero, i1 - i2);
307             break;
308         case 3 + 2:
309             v = complex_t(-creall(c2), i1 - cimagl(c2));
310             break;
311         case 6 + 0:
312             v = complex_t(creall(c1) - r2, cimagl(c1));
313             break;
314         case 6 + 1:
315             v = complex_t(creall(c1), cimagl(c1) - i2);
316             break;
317         case 6 + 2:
318             v = c1 - c2;
319             break;
320         default:
321             assert(0);
322         }
323         new(&ue) ComplexExp(loc, v, type);
324     }
325     else if (e1->op == TOKsymoff)
326     {
327         SymOffExp *soe = (SymOffExp *)e1;
328         new(&ue) SymOffExp(loc, soe->var, soe->offset - e2->toInteger());
329         ue.exp()->type = type;
330     }
331     else
332     {
333         new(&ue) IntegerExp(loc, e1->toInteger() - e2->toInteger(), type);
334     }
335     return ue;
336 }
337
338 UnionExp Mul(Loc loc, Type *type, Expression *e1, Expression *e2)
339 {
340     UnionExp ue;
341
342     if (type->isfloating())
343     {
344         complex_t c = complex_t(CTFloat::zero);
345         real_t r;
346
347         if (e1->type->isreal())
348         {
349             r = e1->toReal();
350             c = e2->toComplex();
351             c = complex_t(r * creall(c), r * cimagl(c));
352         }
353         else if (e1->type->isimaginary())
354         {
355             r = e1->toImaginary();
356             c = e2->toComplex();
357             c = complex_t(-r * cimagl(c), r * creall(c));
358         }
359         else if (e2->type->isreal())
360         {
361             r = e2->toReal();
362             c = e1->toComplex();
363             c = complex_t(r * creall(c), r * cimagl(c));
364         }
365         else if (e2->type->isimaginary())
366         {
367             r = e2->toImaginary();
368             c = e1->toComplex();
369             c = complex_t(-r * cimagl(c), r * creall(c));
370         }
371         else
372             c = e1->toComplex() * e2->toComplex();
373
374         if (type->isreal())
375             new(&ue) RealExp(loc, creall(c), type);
376         else if (type->isimaginary())
377             new(&ue) RealExp(loc, cimagl(c), type);
378         else if (type->iscomplex())
379             new(&ue) ComplexExp(loc, c, type);
380         else
381             assert(0);
382     }
383     else
384     {
385         new(&ue) IntegerExp(loc, e1->toInteger() * e2->toInteger(), type);
386     }
387     return ue;
388 }
389
390 UnionExp Div(Loc loc, Type *type, Expression *e1, Expression *e2)
391 {
392     UnionExp ue;
393
394     if (type->isfloating())
395     {
396         complex_t c = complex_t(CTFloat::zero);
397         real_t r;
398
399         //e1->type->print();
400         //e2->type->print();
401         if (e2->type->isreal())
402         {
403             if (e1->type->isreal())
404             {
405                 new(&ue) RealExp(loc, e1->toReal() / e2->toReal(), type);
406                 return ue;
407             }
408             r = e2->toReal();
409             c = e1->toComplex();
410             c = complex_t(creall(c) / r, cimagl(c) / r);
411         }
412         else if (e2->type->isimaginary())
413         {
414             r = e2->toImaginary();
415             c = e1->toComplex();
416             c = complex_t(cimagl(c) / r, -creall(c) / r);
417         }
418         else
419         {
420             c = e1->toComplex() / e2->toComplex();
421         }
422
423         if (type->isreal())
424             new(&ue) RealExp(loc, creall(c), type);
425         else if (type->isimaginary())
426             new(&ue) RealExp(loc, cimagl(c), type);
427         else if (type->iscomplex())
428             new(&ue) ComplexExp(loc, c, type);
429         else
430             assert(0);
431     }
432     else
433     {
434         sinteger_t n1;
435         sinteger_t n2;
436         sinteger_t n;
437
438         n1 = e1->toInteger();
439         n2 = e2->toInteger();
440         if (n2 == 0)
441         {
442             e2->error("divide by 0");
443             new(&ue) ErrorExp();
444             return ue;
445         }
446         if (n2 == -1 && !type->isunsigned())
447         {
448             // Check for int.min / -1
449             if ((dinteger_t)n1 == 0xFFFFFFFF80000000ULL && type->toBasetype()->ty != Tint64)
450             {
451                 e2->error("integer overflow: int.min / -1");
452                 new(&ue) ErrorExp();
453                 return ue;
454             }
455             else if ((dinteger_t)n1 == 0x8000000000000000LL) // long.min / -1
456             {
457                 e2->error("integer overflow: long.min / -1");
458                 new(&ue) ErrorExp();
459                 return ue;
460             }
461         }
462         if (e1->type->isunsigned() || e2->type->isunsigned())
463             n = ((dinteger_t) n1) / ((dinteger_t) n2);
464         else
465             n = n1 / n2;
466         new(&ue) IntegerExp(loc, n, type);
467     }
468     return ue;
469 }
470
471 UnionExp Mod(Loc loc, Type *type, Expression *e1, Expression *e2)
472 {
473     UnionExp ue;
474
475     if (type->isfloating())
476     {
477         complex_t c = complex_t(CTFloat::zero);
478
479         if (e2->type->isreal())
480         {
481             real_t r2 = e2->toReal();
482
483 #ifdef IN_GCC
484             c = complex_t(e1->toReal() % r2, e1->toImaginary() % r2);
485 #else
486             c = complex_t(::fmodl(e1->toReal(), r2), ::fmodl(e1->toImaginary(), r2));
487 #endif
488         }
489         else if (e2->type->isimaginary())
490         {
491             real_t i2 = e2->toImaginary();
492
493 #ifdef IN_GCC
494             c = complex_t(e1->toReal() % i2, e1->toImaginary() % i2);
495 #else
496             c = complex_t(::fmodl(e1->toReal(), i2), ::fmodl(e1->toImaginary(), i2));
497 #endif
498         }
499         else
500             assert(0);
501
502         if (type->isreal())
503             new(&ue) RealExp(loc, creall(c), type);
504         else if (type->isimaginary())
505             new(&ue) RealExp(loc, cimagl(c), type);
506         else if (type->iscomplex())
507             new(&ue) ComplexExp(loc, c, type);
508         else
509             assert(0);
510     }
511     else
512     {
513         sinteger_t n1;
514         sinteger_t n2;
515         sinteger_t n;
516
517         n1 = e1->toInteger();
518         n2 = e2->toInteger();
519         if (n2 == 0)
520         {
521             e2->error("divide by 0");
522             new(&ue) ErrorExp();
523             return ue;
524         }
525         if (n2 == -1 && !type->isunsigned())
526         {
527             // Check for int.min % -1
528             if ((dinteger_t)n1 == 0xFFFFFFFF80000000ULL && type->toBasetype()->ty != Tint64)
529             {
530                 e2->error("integer overflow: int.min %% -1");
531                 new(&ue) ErrorExp();
532                 return ue;
533             }
534             else if ((dinteger_t)n1 == 0x8000000000000000LL) // long.min % -1
535             {
536                 e2->error("integer overflow: long.min %% -1");
537                 new(&ue) ErrorExp();
538                 return ue;
539             }
540         }
541         if (e1->type->isunsigned() || e2->type->isunsigned())
542             n = ((dinteger_t) n1) % ((dinteger_t) n2);
543         else
544             n = n1 % n2;
545         new(&ue) IntegerExp(loc, n, type);
546     }
547     return ue;
548 }
549
550 UnionExp Pow(Loc loc, Type *type, Expression *e1, Expression *e2)
551 {
552     UnionExp ue;
553
554     // Handle integer power operations.
555     if (e2->type->isintegral())
556     {
557         dinteger_t n = e2->toInteger();
558         bool neg;
559
560         if (!e2->type->isunsigned() && (sinteger_t)n < 0)
561         {
562             if (e1->type->isintegral())
563             {
564                 new(&ue) CTFEExp(TOKcantexp);
565                 return ue;
566             }
567
568             // Don't worry about overflow, from now on n is unsigned.
569             neg = true;
570             n = -n;
571         }
572         else
573             neg = false;
574
575         UnionExp ur, uv;
576         if (e1->type->iscomplex())
577         {
578             new(&ur) ComplexExp(loc, e1->toComplex(), e1->type);
579             new(&uv) ComplexExp(loc, complex_t(CTFloat::one), e1->type);
580         }
581         else if (e1->type->isfloating())
582         {
583             new(&ur) RealExp(loc, e1->toReal(), e1->type);
584             new(&uv) RealExp(loc, CTFloat::one, e1->type);
585         }
586         else
587         {
588             new(&ur) IntegerExp(loc, e1->toInteger(), e1->type);
589             new(&uv) IntegerExp(loc, 1, e1->type);
590         }
591
592         Expression* r = ur.exp();
593         Expression* v = uv.exp();
594         while (n != 0)
595         {
596             if (n & 1)
597             {
598                 // v = v * r;
599                 uv = Mul(loc, v->type, v, r);
600             }
601             n >>= 1;
602             // r = r * r
603             ur = Mul(loc, r->type, r, r);
604         }
605
606         if (neg)
607         {
608             // ue = 1.0 / v
609             UnionExp one;
610             new(&one) RealExp(loc, CTFloat::one, v->type);
611             uv = Div(loc, v->type, one.exp(), v);
612         }
613
614         if (type->iscomplex())
615             new(&ue) ComplexExp(loc, v->toComplex(), type);
616         else if (type->isintegral())
617             new(&ue) IntegerExp(loc, v->toInteger(), type);
618         else
619             new(&ue) RealExp(loc, v->toReal(), type);
620     }
621     else if (e2->type->isfloating())
622     {
623         // x ^^ y for x < 0 and y not an integer is not defined; so set result as NaN
624         if (e1->toReal() < CTFloat::zero)
625         {
626             new(&ue) RealExp(loc, Target::RealProperties::nan, type);
627         }
628         else
629             new(&ue) CTFEExp(TOKcantexp);
630     }
631     else
632         new(&ue) CTFEExp(TOKcantexp);
633
634     return ue;
635 }
636
637 UnionExp Shl(Loc loc, Type *type, Expression *e1, Expression *e2)
638 {
639     UnionExp ue;
640     new(&ue) IntegerExp(loc, e1->toInteger() << e2->toInteger(), type);
641     return ue;
642 }
643
644 UnionExp Shr(Loc loc, Type *type, Expression *e1, Expression *e2)
645 {
646     UnionExp ue;
647     dinteger_t value = e1->toInteger();
648     dinteger_t dcount = e2->toInteger();
649     assert(dcount <= 0xFFFFFFFF);
650     unsigned count = (unsigned)dcount;
651     switch (e1->type->toBasetype()->ty)
652     {
653         case Tint8:
654                 value = (d_int8)(value) >> count;
655                 break;
656
657         case Tuns8:
658         case Tchar:
659                 value = (d_uns8)(value) >> count;
660                 break;
661
662         case Tint16:
663                 value = (d_int16)(value) >> count;
664                 break;
665
666         case Tuns16:
667         case Twchar:
668                 value = (d_uns16)(value) >> count;
669                 break;
670
671         case Tint32:
672                 value = (d_int32)(value) >> count;
673                 break;
674
675         case Tuns32:
676         case Tdchar:
677                 value = (d_uns32)(value) >> count;
678                 break;
679
680         case Tint64:
681                 value = (d_int64)(value) >> count;
682                 break;
683
684         case Tuns64:
685                 value = (d_uns64)(value) >> count;
686                 break;
687
688         case Terror:
689                 new(&ue) ErrorExp();
690                 return ue;
691
692         default:
693                 assert(0);
694     }
695     new(&ue) IntegerExp(loc, value, type);
696     return ue;
697 }
698
699 UnionExp Ushr(Loc loc, Type *type, Expression *e1, Expression *e2)
700 {
701     UnionExp ue;
702     dinteger_t value = e1->toInteger();
703     dinteger_t dcount = e2->toInteger();
704     assert(dcount <= 0xFFFFFFFF);
705     unsigned count = (unsigned)dcount;
706     switch (e1->type->toBasetype()->ty)
707     {
708         case Tint8:
709         case Tuns8:
710         case Tchar:
711                 // Possible only with >>>=. >>> always gets promoted to int.
712                 value = (value & 0xFF) >> count;
713                 break;
714
715         case Tint16:
716         case Tuns16:
717         case Twchar:
718                 // Possible only with >>>=. >>> always gets promoted to int.
719                 value = (value & 0xFFFF) >> count;
720                 break;
721
722         case Tint32:
723         case Tuns32:
724         case Tdchar:
725                 value = (value & 0xFFFFFFFF) >> count;
726                 break;
727
728         case Tint64:
729         case Tuns64:
730                 value = (d_uns64)(value) >> count;
731                 break;
732
733         case Terror:
734                 new(&ue) ErrorExp();
735                 return ue;
736
737         default:
738                 assert(0);
739     }
740     new(&ue) IntegerExp(loc, value, type);
741     return ue;
742 }
743
744 UnionExp And(Loc loc, Type *type, Expression *e1, Expression *e2)
745 {
746     UnionExp ue;
747     new(&ue) IntegerExp(loc, e1->toInteger() & e2->toInteger(), type);
748     return ue;
749 }
750
751 UnionExp Or(Loc loc, Type *type, Expression *e1, Expression *e2)
752 {
753     UnionExp ue;
754     new(&ue) IntegerExp(loc, e1->toInteger() | e2->toInteger(), type);
755     return ue;
756 }
757
758 UnionExp Xor(Loc loc, Type *type, Expression *e1, Expression *e2)
759 {
760     UnionExp ue;
761     new(&ue) IntegerExp(loc, e1->toInteger() ^ e2->toInteger(), type);
762     return ue;
763 }
764
765 /* Also returns TOKcantexp if cannot be computed.
766  */
767 UnionExp Equal(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2)
768 {
769     UnionExp ue;
770     int cmp = 0;
771     real_t r1;
772     real_t r2;
773
774     //printf("Equal(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
775
776     assert(op == TOKequal || op == TOKnotequal);
777
778     if (e1->op == TOKnull)
779     {
780         if (e2->op == TOKnull)
781             cmp = 1;
782         else if (e2->op == TOKstring)
783         {
784             StringExp *es2 = (StringExp *)e2;
785             cmp = (0 == es2->len);
786         }
787         else if (e2->op == TOKarrayliteral)
788         {
789             ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
790             cmp = !es2->elements || (0 == es2->elements->dim);
791         }
792         else
793         {
794             new(&ue) CTFEExp(TOKcantexp);
795             return ue;
796         }
797     }
798     else if (e2->op == TOKnull)
799     {
800         if (e1->op == TOKstring)
801         {
802             StringExp *es1 = (StringExp *)e1;
803             cmp = (0 == es1->len);
804         }
805         else if (e1->op == TOKarrayliteral)
806         {
807             ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
808             cmp = !es1->elements || (0 == es1->elements->dim);
809         }
810         else
811         {
812             new(&ue) CTFEExp(TOKcantexp);
813             return ue;
814         }
815     }
816     else if (e1->op == TOKstring && e2->op == TOKstring)
817     {
818         StringExp *es1 = (StringExp *)e1;
819         StringExp *es2 = (StringExp *)e2;
820
821         if (es1->sz != es2->sz)
822         {
823             assert(global.errors);
824             new(&ue) CTFEExp(TOKcantexp);
825             return ue;
826         }
827         if (es1->len == es2->len &&
828             memcmp(es1->string, es2->string, es1->sz * es1->len) == 0)
829             cmp = 1;
830         else
831             cmp = 0;
832     }
833     else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral)
834     {
835         ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
836         ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
837
838         if ((!es1->elements || !es1->elements->dim) &&
839             (!es2->elements || !es2->elements->dim))
840             cmp = 1;            // both arrays are empty
841         else if (!es1->elements || !es2->elements)
842             cmp = 0;
843         else if (es1->elements->dim != es2->elements->dim)
844             cmp = 0;
845         else
846         {
847             for (size_t i = 0; i < es1->elements->dim; i++)
848             {
849                 Expression *ee1 = es1->getElement(i);
850                 Expression *ee2 = es2->getElement(i);
851                 ue = Equal(TOKequal, loc, Type::tint32, ee1, ee2);
852                 if (CTFEExp::isCantExp(ue.exp()))
853                     return ue;
854                 cmp = (int)ue.exp()->toInteger();
855                 if (cmp == 0)
856                     break;
857             }
858         }
859     }
860     else if (e1->op == TOKarrayliteral && e2->op == TOKstring)
861     {
862         // Swap operands and use common code
863         Expression *etmp = e1;
864         e1 = e2;
865         e2 = etmp;
866         goto Lsa;
867     }
868     else if (e1->op == TOKstring && e2->op == TOKarrayliteral)
869     {
870      Lsa:
871         StringExp *es1 = (StringExp *)e1;
872         ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
873         size_t dim1 = es1->len;
874         size_t dim2 = es2->elements ? es2->elements->dim : 0;
875         if (dim1 != dim2)
876             cmp = 0;
877         else
878         {
879             cmp = 1;            // if dim1 winds up being 0
880             for (size_t i = 0; i < dim1; i++)
881             {
882                 uinteger_t c = es1->charAt(i);
883                 Expression *ee2 = es2->getElement(i);
884                 if (ee2->isConst() != 1)
885                 {
886                     new(&ue) CTFEExp(TOKcantexp);
887                     return ue;
888                 }
889                 cmp = (c == ee2->toInteger());
890                 if (cmp == 0)
891                     break;
892             }
893         }
894     }
895     else if (e1->op == TOKstructliteral && e2->op == TOKstructliteral)
896     {
897         StructLiteralExp *es1 = (StructLiteralExp *)e1;
898         StructLiteralExp *es2 = (StructLiteralExp *)e2;
899
900         if (es1->sd != es2->sd)
901             cmp = 0;
902         else if ((!es1->elements || !es1->elements->dim) &&
903             (!es2->elements || !es2->elements->dim))
904             cmp = 1;            // both arrays are empty
905         else if (!es1->elements || !es2->elements)
906             cmp = 0;
907         else if (es1->elements->dim != es2->elements->dim)
908             cmp = 0;
909         else
910         {
911             cmp = 1;
912             for (size_t i = 0; i < es1->elements->dim; i++)
913             {
914                 Expression *ee1 = (*es1->elements)[i];
915                 Expression *ee2 = (*es2->elements)[i];
916
917                 if (ee1 == ee2)
918                     continue;
919                 if (!ee1 || !ee2)
920                 {
921                     cmp = 0;
922                     break;
923                 }
924                 ue = Equal(TOKequal, loc, Type::tint32, ee1, ee2);
925                 if (ue.exp()->op == TOKcantexp)
926                     return ue;
927                 cmp = (int)ue.exp()->toInteger();
928                 if (cmp == 0)
929                     break;
930             }
931         }
932     }
933     else if (e1->isConst() != 1 || e2->isConst() != 1)
934     {
935         new(&ue) CTFEExp(TOKcantexp);
936         return ue;
937     }
938     else if (e1->type->isreal())
939     {
940         r1 = e1->toReal();
941         r2 = e2->toReal();
942         goto L1;
943     }
944     else if (e1->type->isimaginary())
945     {
946         r1 = e1->toImaginary();
947         r2 = e2->toImaginary();
948      L1:
949         if (CTFloat::isNaN(r1) || CTFloat::isNaN(r2)) // if unordered
950         {
951             cmp = 0;
952         }
953         else
954         {
955             cmp = (r1 == r2);
956         }
957     }
958     else if (e1->type->iscomplex())
959     {
960         cmp = e1->toComplex() == e2->toComplex();
961     }
962     else if (e1->type->isintegral() || e1->type->toBasetype()->ty == Tpointer)
963     {
964         cmp = (e1->toInteger() == e2->toInteger());
965     }
966     else
967     {
968         new(&ue) CTFEExp(TOKcantexp);
969         return ue;
970     }
971
972     if (op == TOKnotequal)
973         cmp ^= 1;
974     new(&ue) IntegerExp(loc, cmp, type);
975     return ue;
976 }
977
978 UnionExp Identity(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2)
979 {
980     UnionExp ue;
981     int cmp;
982
983     if (e1->op == TOKnull)
984     {
985         cmp = (e2->op == TOKnull);
986     }
987     else if (e2->op == TOKnull)
988     {
989         cmp = 0;
990     }
991     else if (e1->op == TOKsymoff && e2->op == TOKsymoff)
992     {
993         SymOffExp *es1 = (SymOffExp *)e1;
994         SymOffExp *es2 = (SymOffExp *)e2;
995
996         cmp = (es1->var == es2->var && es1->offset == es2->offset);
997     }
998     else
999     {
1000        if (e1->type->isreal())
1001        {
1002            cmp = RealEquals(e1->toReal(), e2->toReal());
1003        }
1004        else if (e1->type->isimaginary())
1005        {
1006            cmp = RealEquals(e1->toImaginary(), e2->toImaginary());
1007        }
1008        else if (e1->type->iscomplex())
1009        {
1010            complex_t v1 = e1->toComplex();
1011            complex_t v2 = e2->toComplex();
1012            cmp = RealEquals(creall(v1), creall(v2)) &&
1013                  RealEquals(cimagl(v1), cimagl(v1));
1014         }
1015         else
1016         {
1017            ue = Equal((op == TOKidentity) ? TOKequal : TOKnotequal, loc, type, e1, e2);
1018            return ue;
1019         }
1020     }
1021     if (op == TOKnotidentity)
1022         cmp ^= 1;
1023     new(&ue) IntegerExp(loc, cmp, type);
1024     return ue;
1025 }
1026
1027
1028 UnionExp Cmp(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2)
1029 {
1030     UnionExp ue;
1031     dinteger_t n;
1032     real_t r1;
1033     real_t r2;
1034
1035     //printf("Cmp(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
1036
1037     if (e1->op == TOKstring && e2->op == TOKstring)
1038     {
1039         StringExp *es1 = (StringExp *)e1;
1040         StringExp *es2 = (StringExp *)e2;
1041         size_t sz = es1->sz;
1042         assert(sz == es2->sz);
1043
1044         size_t len = es1->len;
1045         if (es2->len < len)
1046             len = es2->len;
1047
1048         int rawCmp = memcmp(es1->string, es2->string, sz * len);
1049         if (rawCmp == 0)
1050             rawCmp = (int)(es1->len - es2->len);
1051         n = specificCmp(op, rawCmp);
1052     }
1053     else if (e1->isConst() != 1 || e2->isConst() != 1)
1054     {
1055         new(&ue) CTFEExp(TOKcantexp);
1056         return ue;
1057     }
1058     else if (e1->type->isreal())
1059     {
1060         r1 = e1->toReal();
1061         r2 = e2->toReal();
1062         goto L1;
1063     }
1064     else if (e1->type->isimaginary())
1065     {
1066         r1 = e1->toImaginary();
1067         r2 = e2->toImaginary();
1068      L1:
1069         n = realCmp(op, r1, r2);
1070     }
1071     else if (e1->type->iscomplex())
1072     {
1073         assert(0);
1074     }
1075     else
1076     {
1077         sinteger_t n1;
1078         sinteger_t n2;
1079
1080         n1 = e1->toInteger();
1081         n2 = e2->toInteger();
1082         if (e1->type->isunsigned() || e2->type->isunsigned())
1083             n = intUnsignedCmp(op, n1, n2);
1084         else
1085             n = intSignedCmp(op, n1, n2);
1086     }
1087     new(&ue) IntegerExp(loc, n, type);
1088     return ue;
1089 }
1090
1091 /* Also returns TOKcantexp if cannot be computed.
1092  *  to: type to cast to
1093  *  type: type to paint the result
1094  */
1095
1096 UnionExp Cast(Loc loc, Type *type, Type *to, Expression *e1)
1097 {
1098     UnionExp ue;
1099     Type *tb = to->toBasetype();
1100     Type *typeb = type->toBasetype();
1101
1102     //printf("Cast(type = %s, to = %s, e1 = %s)\n", type->toChars(), to->toChars(), e1->toChars());
1103     //printf("\te1->type = %s\n", e1->type->toChars());
1104     if (e1->type->equals(type) && type->equals(to))
1105     {
1106         new(&ue) UnionExp(e1);
1107         return ue;
1108     }
1109
1110     if (e1->op == TOKvector && ((TypeVector *)e1->type)->basetype->equals(type) && type->equals(to))
1111     {
1112         Expression *ex = ((VectorExp *)e1)->e1;
1113         new(&ue) UnionExp(ex);
1114         return ue;
1115     }
1116
1117     if (e1->type->implicitConvTo(to) >= MATCHconst ||
1118         to->implicitConvTo(e1->type) >= MATCHconst)
1119     {
1120         goto L1;
1121     }
1122
1123     // Allow covariant converions of delegates
1124     // (Perhaps implicit conversion from pure to impure should be a MATCHconst,
1125     // then we wouldn't need this extra check.)
1126     if (e1->type->toBasetype()->ty == Tdelegate &&
1127         e1->type->implicitConvTo(to) == MATCHconvert)
1128     {
1129         goto L1;
1130     }
1131
1132     /* Allow casting from one string type to another
1133      */
1134     if (e1->op == TOKstring)
1135     {
1136         if (tb->ty == Tarray && typeb->ty == Tarray &&
1137             tb->nextOf()->size() == typeb->nextOf()->size())
1138         {
1139             goto L1;
1140         }
1141     }
1142
1143     if (e1->op == TOKarrayliteral && typeb == tb)
1144     {
1145 L1:
1146         Expression *ex = expType(to, e1);
1147         new(&ue) UnionExp(ex);
1148         return ue;
1149     }
1150
1151     if (e1->isConst() != 1)
1152     {
1153         new(&ue) CTFEExp(TOKcantexp);
1154     }
1155     else if (tb->ty == Tbool)
1156     {
1157         new(&ue) IntegerExp(loc, e1->toInteger() != 0, type);
1158     }
1159     else if (type->isintegral())
1160     {
1161         if (e1->type->isfloating())
1162         {
1163             dinteger_t result;
1164             real_t r = e1->toReal();
1165
1166             switch (typeb->ty)
1167             {
1168                 case Tint8:
1169                     result = (d_int8)(sinteger_t)r;
1170                     break;
1171                 case Tchar:
1172                 case Tuns8:
1173                     result = (d_uns8)(dinteger_t)r;
1174                     break;
1175                 case Tint16:
1176                     result = (d_int16)(sinteger_t)r;
1177                     break;
1178                 case Twchar:
1179                 case Tuns16:
1180                     result = (d_uns16)(dinteger_t)r;
1181                     break;
1182                 case Tint32:
1183                     result = (d_int32)r;
1184                     break;
1185                 case Tdchar:
1186                 case Tuns32:
1187                     result = (d_uns32)r;
1188                     break;
1189                 case Tint64:
1190                     result = (d_int64)r;
1191                     break;
1192                 case Tuns64:
1193                     result = (d_uns64)r;
1194                     break;
1195                 default:
1196                     assert(0);
1197             }
1198
1199             new(&ue) IntegerExp(loc, result, type);
1200         }
1201         else if (type->isunsigned())
1202             new(&ue) IntegerExp(loc, e1->toUInteger(), type);
1203         else
1204             new(&ue) IntegerExp(loc, e1->toInteger(), type);
1205     }
1206     else if (tb->isreal())
1207     {
1208         real_t value = e1->toReal();
1209
1210         new(&ue) RealExp(loc, value, type);
1211     }
1212     else if (tb->isimaginary())
1213     {
1214         real_t value = e1->toImaginary();
1215
1216         new(&ue) RealExp(loc, value, type);
1217     }
1218     else if (tb->iscomplex())
1219     {
1220         complex_t value = e1->toComplex();
1221
1222         new(&ue) ComplexExp(loc, value, type);
1223     }
1224     else if (tb->isscalar())
1225     {
1226         new(&ue) IntegerExp(loc, e1->toInteger(), type);
1227     }
1228     else if (tb->ty == Tvoid)
1229     {
1230         new(&ue) CTFEExp(TOKcantexp);
1231     }
1232     else if (tb->ty == Tstruct && e1->op == TOKint64)
1233     {
1234         // Struct = 0;
1235         StructDeclaration *sd = tb->toDsymbol(NULL)->isStructDeclaration();
1236         assert(sd);
1237         Expressions *elements = new Expressions;
1238         for (size_t i = 0; i < sd->fields.dim; i++)
1239         {
1240             VarDeclaration *v = sd->fields[i];
1241             UnionExp zero;
1242             new(&zero) IntegerExp(0);
1243             ue = Cast(loc, v->type, v->type, zero.exp());
1244             if (ue.exp()->op == TOKcantexp)
1245                 return ue;
1246             elements->push(ue.exp()->copy());
1247         }
1248         new(&ue) StructLiteralExp(loc, sd, elements);
1249         ue.exp()->type = type;
1250     }
1251     else
1252     {
1253         if (type != Type::terror)
1254         {
1255             // have to change to Internal Compiler Error
1256             // all invalid casts should be handled already in Expression::castTo().
1257             error(loc, "cannot cast %s to %s", e1->type->toChars(), type->toChars());
1258         }
1259         new(&ue) ErrorExp();
1260     }
1261     return ue;
1262 }
1263
1264
1265 UnionExp ArrayLength(Type *type, Expression *e1)
1266 {
1267     UnionExp ue;
1268     Loc loc = e1->loc;
1269
1270     if (e1->op == TOKstring)
1271     {
1272         StringExp *es1 = (StringExp *)e1;
1273
1274         new(&ue) IntegerExp(loc, es1->len, type);
1275     }
1276     else if (e1->op == TOKarrayliteral)
1277     {
1278         ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
1279         size_t dim = ale->elements ? ale->elements->dim : 0;
1280
1281         new(&ue) IntegerExp(loc, dim, type);
1282     }
1283     else if (e1->op == TOKassocarrayliteral)
1284     {
1285         AssocArrayLiteralExp *ale = (AssocArrayLiteralExp *)e1;
1286         size_t dim = ale->keys->dim;
1287
1288         new(&ue) IntegerExp(loc, dim, type);
1289     }
1290     else if (e1->type->toBasetype()->ty == Tsarray)
1291     {
1292         Expression *e = ((TypeSArray *)e1->type->toBasetype())->dim;
1293         new(&ue) UnionExp(e);
1294     }
1295     else
1296         new(&ue) CTFEExp(TOKcantexp);
1297     return ue;
1298 }
1299
1300 /* Also return TOKcantexp if this fails
1301  */
1302 UnionExp Index(Type *type, Expression *e1, Expression *e2)
1303 {
1304     UnionExp ue;
1305     Loc loc = e1->loc;
1306
1307     //printf("Index(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
1308     assert(e1->type);
1309     if (e1->op == TOKstring && e2->op == TOKint64)
1310     {
1311         StringExp *es1 = (StringExp *)e1;
1312         uinteger_t i = e2->toInteger();
1313
1314         if (i >= es1->len)
1315         {
1316             e1->error("string index %llu is out of bounds [0 .. %llu]", i, (ulonglong)es1->len);
1317             new(&ue) ErrorExp();
1318         }
1319         else
1320         {
1321             new(&ue) IntegerExp(loc, es1->charAt(i), type);
1322         }
1323     }
1324     else if (e1->type->toBasetype()->ty == Tsarray && e2->op == TOKint64)
1325     {
1326         TypeSArray *tsa = (TypeSArray *)e1->type->toBasetype();
1327         uinteger_t length = tsa->dim->toInteger();
1328         uinteger_t i = e2->toInteger();
1329
1330         if (i >= length)
1331         {
1332             e1->error("array index %llu is out of bounds %s[0 .. %llu]", i, e1->toChars(), length);
1333             new(&ue) ErrorExp();
1334         }
1335         else if (e1->op == TOKarrayliteral)
1336         {
1337             ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
1338             Expression *e = ale->getElement((size_t)i);
1339             e->type = type;
1340             e->loc = loc;
1341             if (hasSideEffect(e))
1342                 new(&ue) CTFEExp(TOKcantexp);
1343             else
1344                 new(&ue) UnionExp(e);
1345         }
1346         else
1347             new(&ue) CTFEExp(TOKcantexp);
1348     }
1349     else if (e1->type->toBasetype()->ty == Tarray && e2->op == TOKint64)
1350     {
1351         uinteger_t i = e2->toInteger();
1352
1353         if (e1->op == TOKarrayliteral)
1354         {
1355             ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
1356             if (i >= ale->elements->dim)
1357             {
1358                 e1->error("array index %llu is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim);
1359                 new(&ue) ErrorExp();
1360             }
1361             else
1362             {
1363                 Expression *e = ale->getElement((size_t)i);
1364                 e->type = type;
1365                 e->loc = loc;
1366                 if (hasSideEffect(e))
1367                     new(&ue) CTFEExp(TOKcantexp);
1368                 else
1369                     new(&ue) UnionExp(e);
1370             }
1371         }
1372         else
1373             new(&ue) CTFEExp(TOKcantexp);
1374     }
1375     else if (e1->op == TOKassocarrayliteral)
1376     {
1377         AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)e1;
1378         /* Search the keys backwards, in case there are duplicate keys
1379          */
1380         for (size_t i = ae->keys->dim; i;)
1381         {
1382             i--;
1383             Expression *ekey = (*ae->keys)[i];
1384             ue = Equal(TOKequal, loc, Type::tbool, ekey, e2);
1385             if (CTFEExp::isCantExp(ue.exp()))
1386                 return ue;
1387             if (ue.exp()->isBool(true))
1388             {
1389                 Expression *e = (*ae->values)[i];
1390                 e->type = type;
1391                 e->loc = loc;
1392                 if (hasSideEffect(e))
1393                     new(&ue) CTFEExp(TOKcantexp);
1394                 else
1395                     new(&ue) UnionExp(e);
1396                 return ue;
1397             }
1398         }
1399         new(&ue) CTFEExp(TOKcantexp);
1400     }
1401     else
1402         new(&ue) CTFEExp(TOKcantexp);
1403     return ue;
1404 }
1405
1406 /* Also return TOKcantexp if this fails
1407  */
1408 UnionExp Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
1409 {
1410     UnionExp ue;
1411     Loc loc = e1->loc;
1412
1413     if (e1->op == TOKstring && lwr->op == TOKint64 && upr->op == TOKint64)
1414     {
1415         StringExp *es1 = (StringExp *)e1;
1416         uinteger_t ilwr = lwr->toInteger();
1417         uinteger_t iupr = upr->toInteger();
1418
1419         if (iupr > es1->len || ilwr > iupr)
1420         {
1421             e1->error("string slice [%llu .. %llu] is out of bounds", ilwr, iupr);
1422             new(&ue) ErrorExp();
1423         }
1424         else
1425         {
1426             size_t len = (size_t)(iupr - ilwr);
1427             unsigned char sz = es1->sz;
1428
1429             void *s = mem.xmalloc((len + 1) * sz);
1430             memcpy((char *)s, (char *)es1->string + ilwr * sz, len * sz);
1431             memset((char *)s + len * sz, 0, sz);
1432
1433             new(&ue) StringExp(loc, s, len, es1->postfix);
1434             StringExp *es = (StringExp *)ue.exp();
1435             es->sz = sz;
1436             es->committed = es1->committed;
1437             es->type = type;
1438         }
1439     }
1440     else if (e1->op == TOKarrayliteral &&
1441             lwr->op == TOKint64 && upr->op == TOKint64 &&
1442             !hasSideEffect(e1))
1443     {
1444         ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
1445         uinteger_t ilwr = lwr->toInteger();
1446         uinteger_t iupr = upr->toInteger();
1447
1448         if (iupr > es1->elements->dim || ilwr > iupr)
1449         {
1450             e1->error("array slice [%llu .. %llu] is out of bounds", ilwr, iupr);
1451             new(&ue) ErrorExp();
1452         }
1453         else
1454         {
1455             Expressions *elements = new Expressions();
1456             elements->setDim((size_t)(iupr - ilwr));
1457             memcpy(elements->tdata(),
1458                    es1->elements->tdata() + ilwr,
1459                    (size_t)(iupr - ilwr) * sizeof((*es1->elements)[0]));
1460             new(&ue) ArrayLiteralExp(e1->loc, elements);
1461             ue.exp()->type = type;
1462         }
1463     }
1464     else
1465         new(&ue) CTFEExp(TOKcantexp);
1466     assert(ue.exp()->type);
1467     return ue;
1468 }
1469
1470 /* Set a slice of char/integer array literal 'existingAE' from a string 'newval'.
1471  * existingAE[firstIndex..firstIndex+newval.length] = newval.
1472  */
1473 void sliceAssignArrayLiteralFromString(ArrayLiteralExp *existingAE, StringExp *newval, size_t firstIndex)
1474 {
1475     size_t newlen =  newval->len;
1476     size_t sz = newval->sz;
1477     void *s = newval->string;
1478     Type *elemType = existingAE->type->nextOf();
1479     for (size_t j = 0; j < newlen; j++)
1480     {
1481         dinteger_t val;
1482         switch (sz)
1483         {
1484             case 1:     val = (( utf8_t *)s)[j];    break;
1485             case 2:     val = ((utf16_t *)s)[j];    break;
1486             case 4:     val = ((utf32_t *)s)[j];    break;
1487             default:    assert(0);                  break;
1488         }
1489         (*existingAE->elements)[j + firstIndex]
1490             = new IntegerExp(newval->loc, val, elemType);
1491     }
1492 }
1493
1494 /* Set a slice of string 'existingSE' from a char array literal 'newae'.
1495  *   existingSE[firstIndex..firstIndex+newae.length] = newae.
1496  */
1497 void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *newae, size_t firstIndex)
1498 {
1499     void *s = existingSE->string;
1500     for (size_t j = 0; j < newae->elements->dim; j++)
1501     {
1502         unsigned val = (unsigned)newae->getElement(j)->toInteger();
1503         switch (existingSE->sz)
1504         {
1505             case 1:     (( utf8_t *)s)[j + firstIndex] = ( utf8_t)val;  break;
1506             case 2:     ((utf16_t *)s)[j + firstIndex] = (utf16_t)val;  break;
1507             case 4:     ((utf32_t *)s)[j + firstIndex] = (utf32_t)val;  break;
1508             default:    assert(0);                                      break;
1509         }
1510     }
1511 }
1512
1513 /* Set a slice of string 'existingSE' from a string 'newstr'.
1514  *   existingSE[firstIndex..firstIndex+newstr.length] = newstr.
1515  */
1516 void sliceAssignStringFromString(StringExp *existingSE, StringExp *newstr, size_t firstIndex)
1517 {
1518     void *s = existingSE->string;
1519     size_t sz = existingSE->sz;
1520     assert(sz == newstr->sz);
1521     memcpy((char *)s + firstIndex * sz, newstr->string, sz * newstr->len);
1522 }
1523
1524 /* Compare a string slice with another string slice.
1525  * Conceptually equivalent to memcmp( se1[lo1..lo1+len],  se2[lo2..lo2+len])
1526  */
1527 int sliceCmpStringWithString(StringExp *se1, StringExp *se2, size_t lo1, size_t lo2, size_t len)
1528 {
1529     void *s1 = se1->string;
1530     void *s2 = se2->string;
1531     size_t sz = se1->sz;
1532     assert(sz == se2->sz);
1533     return memcmp((char *)s1 + sz * lo1, (char *)s2 + sz * lo2, sz * len);
1534 }
1535
1536 /* Compare a string slice with an array literal slice
1537  * Conceptually equivalent to memcmp( se1[lo1..lo1+len],  ae2[lo2..lo2+len])
1538  */
1539 int sliceCmpStringWithArray(StringExp *se1, ArrayLiteralExp *ae2, size_t lo1, size_t lo2, size_t len)
1540 {
1541     void *s = se1->string;
1542     size_t sz = se1->sz;
1543
1544     for (size_t j = 0; j < len; j++)
1545     {
1546         unsigned val2 = (unsigned)ae2->getElement(j + lo2)->toInteger();
1547         unsigned val1;
1548         switch (sz)
1549         {
1550             case 1:     val1 = (( utf8_t *)s)[j + lo1]; break;
1551             case 2:     val1 = ((utf16_t *)s)[j + lo1]; break;
1552             case 4:     val1 = ((utf32_t *)s)[j + lo1]; break;
1553             default:    assert(0);                      break;
1554         }
1555         int c = val1 - val2;
1556         if (c)
1557             return c;
1558     }
1559     return 0;
1560 }
1561
1562 /* Also return TOKcantexp if this fails
1563  */
1564 UnionExp Cat(Type *type, Expression *e1, Expression *e2)
1565 {
1566     UnionExp ue;
1567     Expression *e = CTFEExp::cantexp;
1568     Loc loc = e1->loc;
1569     Type *t;
1570     Type *t1 = e1->type->toBasetype();
1571     Type *t2 = e2->type->toBasetype();
1572
1573     //printf("Cat(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
1574     //printf("\tt1 = %s, t2 = %s, type = %s\n", t1->toChars(), t2->toChars(), type->toChars());
1575
1576     if (e1->op == TOKnull && (e2->op == TOKint64 || e2->op == TOKstructliteral))
1577     {
1578         e = e2;
1579         t = t1;
1580         goto L2;
1581     }
1582     else if ((e1->op == TOKint64 || e1->op == TOKstructliteral) && e2->op == TOKnull)
1583     {
1584         e = e1;
1585         t = t2;
1586      L2:
1587         Type *tn = e->type->toBasetype();
1588         if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar)
1589         {
1590             // Create a StringExp
1591             if (t->nextOf())
1592                 t = t->nextOf()->toBasetype();
1593             unsigned char sz = (unsigned char)t->size();
1594
1595             dinteger_t v = e->toInteger();
1596
1597             size_t len = (t->ty == tn->ty) ? 1 : utf_codeLength(sz, (dchar_t)v);
1598             void *s = mem.xmalloc((len + 1) * sz);
1599             if (t->ty == tn->ty)
1600                 Port::valcpy(s, v, sz);
1601             else
1602                 utf_encode(sz, s, (dchar_t)v);
1603
1604             // Add terminating 0
1605             memset((char *)s + len * sz, 0, sz);
1606
1607             new(&ue) StringExp(loc, s, len);
1608             StringExp *es = (StringExp *)ue.exp();
1609             es->sz = sz;
1610             es->committed = 1;
1611         }
1612         else
1613         {
1614             // Create an ArrayLiteralExp
1615             Expressions *elements = new Expressions();
1616             elements->push(e);
1617             new(&ue) ArrayLiteralExp(e->loc, elements);
1618         }
1619         ue.exp()->type = type;
1620         assert(ue.exp()->type);
1621         return ue;
1622     }
1623     else if (e1->op == TOKnull && e2->op == TOKnull)
1624     {
1625         if (type == e1->type)
1626         {
1627             // Handle null ~= null
1628             if (t1->ty == Tarray && t2 == t1->nextOf())
1629             {
1630                 new(&ue) ArrayLiteralExp(e1->loc, e2);
1631                 ue.exp()->type = type;
1632                 assert(ue.exp()->type);
1633                 return ue;
1634             }
1635             else
1636             {
1637                 new(&ue) UnionExp(e1);
1638                 assert(ue.exp()->type);
1639                 return ue;
1640             }
1641         }
1642         if (type == e2->type)
1643         {
1644             new(&ue) UnionExp(e2);
1645             assert(ue.exp()->type);
1646             return ue;
1647         }
1648         new(&ue) NullExp(e1->loc, type);
1649         assert(ue.exp()->type);
1650         return ue;
1651     }
1652     else if (e1->op == TOKstring && e2->op == TOKstring)
1653     {
1654         // Concatenate the strings
1655         StringExp *es1 = (StringExp *)e1;
1656         StringExp *es2 = (StringExp *)e2;
1657         size_t len = es1->len + es2->len;
1658         unsigned char sz = es1->sz;
1659
1660         if (sz != es2->sz)
1661         {
1662             /* Can happen with:
1663              *   auto s = "foo"d ~ "bar"c;
1664              */
1665             assert(global.errors);
1666             new(&ue) CTFEExp(TOKcantexp);
1667             assert(ue.exp()->type);
1668             return ue;
1669         }
1670         void *s = mem.xmalloc((len + 1) * sz);
1671         memcpy((char *)s, es1->string, es1->len * sz);
1672         memcpy((char *)s + es1->len * sz, es2->string, es2->len * sz);
1673
1674         // Add terminating 0
1675         memset((char *)s + len * sz, 0, sz);
1676
1677         new(&ue) StringExp(loc, s, len);
1678         StringExp *es = (StringExp *)ue.exp();
1679         es->sz = sz;
1680         es->committed = es1->committed | es2->committed;
1681         es->type = type;
1682         assert(ue.exp()->type);
1683         return ue;
1684     }
1685     else if (e2->op == TOKstring && e1->op == TOKarrayliteral &&
1686         t1->nextOf()->isintegral())
1687     {
1688         // [chars] ~ string --> [chars]
1689         StringExp *es = (StringExp *)e2;
1690         ArrayLiteralExp *ea = (ArrayLiteralExp *)e1;
1691         size_t len = es->len + ea->elements->dim;
1692         Expressions * elems = new Expressions;
1693         elems->setDim(len);
1694         for (size_t i= 0; i < ea->elements->dim; ++i)
1695         {
1696             (*elems)[i] = ea->getElement(i);
1697         }
1698         new(&ue) ArrayLiteralExp(e1->loc, elems);
1699         ArrayLiteralExp *dest = (ArrayLiteralExp *)ue.exp();
1700         dest->type = type;
1701         sliceAssignArrayLiteralFromString(dest, es, ea->elements->dim);
1702         assert(ue.exp()->type);
1703         return ue;
1704     }
1705     else if (e1->op == TOKstring && e2->op == TOKarrayliteral &&
1706         t2->nextOf()->isintegral())
1707     {
1708         // string ~ [chars] --> [chars]
1709         StringExp *es = (StringExp *)e1;
1710         ArrayLiteralExp *ea = (ArrayLiteralExp *)e2;
1711         size_t len = es->len + ea->elements->dim;
1712         Expressions * elems = new Expressions;
1713         elems->setDim(len);
1714         for (size_t i= 0; i < ea->elements->dim; ++i)
1715         {
1716             (*elems)[es->len + i] = ea->getElement(i);
1717         }
1718         new(&ue) ArrayLiteralExp(e1->loc, elems);
1719         ArrayLiteralExp *dest = (ArrayLiteralExp *)ue.exp();
1720         dest->type = type;
1721         sliceAssignArrayLiteralFromString(dest, es, 0);
1722         assert(ue.exp()->type);
1723         return ue;
1724     }
1725     else if (e1->op == TOKstring && e2->op == TOKint64)
1726     {
1727         // string ~ char --> string
1728         StringExp *es1 = (StringExp *)e1;
1729         StringExp *es;
1730         unsigned char sz = es1->sz;
1731         dinteger_t v = e2->toInteger();
1732
1733         // Is it a concatentation of homogenous types?
1734         // (char[] ~ char, wchar[]~wchar, or dchar[]~dchar)
1735         bool homoConcat = (sz == t2->size());
1736         size_t len = es1->len;
1737         len += homoConcat ? 1 : utf_codeLength(sz, (dchar_t)v);
1738
1739         void *s = mem.xmalloc((len + 1) * sz);
1740         memcpy(s, es1->string, es1->len * sz);
1741         if (homoConcat)
1742             Port::valcpy((char *)s + (sz * es1->len), v, sz);
1743         else
1744             utf_encode(sz, (char *)s + (sz * es1->len), (dchar_t)v);
1745
1746         // Add terminating 0
1747         memset((char *)s + len * sz, 0, sz);
1748
1749         new(&ue) StringExp(loc, s, len);
1750         es = (StringExp *)ue.exp();
1751         es->sz = sz;
1752         es->committed = es1->committed;
1753         es->type = type;
1754         assert(ue.exp()->type);
1755         return ue;
1756     }
1757     else if (e1->op == TOKint64 && e2->op == TOKstring)
1758     {
1759         // Concatenate the strings
1760         StringExp *es2 = (StringExp *)e2;
1761         size_t len = 1 + es2->len;
1762         unsigned char sz = es2->sz;
1763         dinteger_t v = e1->toInteger();
1764
1765         void *s = mem.xmalloc((len + 1) * sz);
1766         memcpy((char *)s, &v, sz);
1767         memcpy((char *)s + sz, es2->string, es2->len * sz);
1768
1769         // Add terminating 0
1770         memset((char *)s + len * sz, 0, sz);
1771
1772         new(&ue) StringExp(loc, s, len);
1773         StringExp *es = (StringExp *)ue.exp();
1774         es->sz = sz;
1775         es->committed = es2->committed;
1776         es->type = type;
1777         assert(ue.exp()->type);
1778         return ue;
1779     }
1780     else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral &&
1781         t1->nextOf()->equals(t2->nextOf()))
1782     {
1783         // Concatenate the arrays
1784         Expressions *elems = ArrayLiteralExp::copyElements(e1, e2);
1785
1786         new(&ue) ArrayLiteralExp(e1->loc, elems);
1787
1788         e = ue.exp();
1789         if (type->toBasetype()->ty == Tsarray)
1790         {
1791             e->type = t1->nextOf()->sarrayOf(elems->dim);
1792         }
1793         else
1794             e->type = type;
1795         assert(ue.exp()->type);
1796         return ue;
1797     }
1798     else if (e1->op == TOKarrayliteral && e2->op == TOKnull &&
1799         t1->nextOf()->equals(t2->nextOf()))
1800     {
1801         e = e1;
1802         goto L3;
1803     }
1804     else if (e1->op == TOKnull && e2->op == TOKarrayliteral &&
1805         t1->nextOf()->equals(t2->nextOf()))
1806     {
1807         e = e2;
1808      L3:
1809         // Concatenate the array with null
1810         Expressions *elems = ArrayLiteralExp::copyElements(e);
1811
1812         new(&ue) ArrayLiteralExp(e->loc, elems);
1813
1814         e = ue.exp();
1815         if (type->toBasetype()->ty == Tsarray)
1816         {
1817             e->type = t1->nextOf()->sarrayOf(elems->dim);
1818         }
1819         else
1820             e->type = type;
1821         assert(ue.exp()->type);
1822         return ue;
1823     }
1824     else if ((e1->op == TOKarrayliteral || e1->op == TOKnull) &&
1825         e1->type->toBasetype()->nextOf() &&
1826         e1->type->toBasetype()->nextOf()->equals(e2->type))
1827     {
1828         Expressions *elems = (e1->op == TOKarrayliteral)
1829             ? ArrayLiteralExp::copyElements(e1) : new Expressions();
1830         elems->push(e2);
1831
1832         new(&ue) ArrayLiteralExp(e1->loc, elems);
1833
1834         e = ue.exp();
1835         if (type->toBasetype()->ty == Tsarray)
1836         {
1837             e->type = e2->type->sarrayOf(elems->dim);
1838         }
1839         else
1840             e->type = type;
1841         assert(ue.exp()->type);
1842         return ue;
1843     }
1844     else if (e2->op == TOKarrayliteral &&
1845         e2->type->toBasetype()->nextOf()->equals(e1->type))
1846     {
1847         Expressions *elems = ArrayLiteralExp::copyElements(e1, e2);
1848
1849         new(&ue) ArrayLiteralExp(e2->loc, elems);
1850
1851         e = ue.exp();
1852         if (type->toBasetype()->ty == Tsarray)
1853         {
1854             e->type = e1->type->sarrayOf(elems->dim);
1855         }
1856         else
1857             e->type = type;
1858         assert(ue.exp()->type);
1859         return ue;
1860     }
1861     else if (e1->op == TOKnull && e2->op == TOKstring)
1862     {
1863         t = e1->type;
1864         e = e2;
1865         goto L1;
1866     }
1867     else if (e1->op == TOKstring && e2->op == TOKnull)
1868     {
1869         e = e1;
1870         t = e2->type;
1871       L1:
1872         Type *tb = t->toBasetype();
1873         if (tb->ty == Tarray && tb->nextOf()->equivalent(e->type))
1874         {
1875             Expressions *expressions = new Expressions();
1876             expressions->push(e);
1877             new(&ue) ArrayLiteralExp(loc, expressions);
1878             e = ue.exp();
1879             e->type = t;
1880         }
1881         else
1882         {
1883             new(&ue) UnionExp(e);
1884             e = ue.exp();
1885         }
1886         if (!e->type->equals(type))
1887         {
1888             StringExp *se = (StringExp *)e->copy();
1889             e = se->castTo(NULL, type);
1890             new(&ue) UnionExp(e);
1891             e = ue.exp();
1892         }
1893     }
1894     else
1895         new(&ue) CTFEExp(TOKcantexp);
1896     assert(ue.exp()->type);
1897     return ue;
1898 }
1899
1900 UnionExp Ptr(Type *type, Expression *e1)
1901 {
1902     //printf("Ptr(e1 = %s)\n", e1->toChars());
1903     UnionExp ue;
1904     if (e1->op == TOKadd)
1905     {
1906         AddExp *ae = (AddExp *)e1;
1907         if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64)
1908         {
1909             AddrExp *ade = (AddrExp *)ae->e1;
1910             if (ade->e1->op == TOKstructliteral)
1911             {
1912                 StructLiteralExp *se = (StructLiteralExp *)ade->e1;
1913                 unsigned offset = (unsigned)ae->e2->toInteger();
1914                 Expression *e = se->getField(type, offset);
1915                 if (e)
1916                 {
1917                     new(&ue) UnionExp(e);
1918                     return ue;
1919                 }
1920             }
1921         }
1922     }
1923     new(&ue) CTFEExp(TOKcantexp);
1924     return ue;
1925 }