1:
2: // Copyright (c) 1999-2011 by Digital Mars
3: // All Rights Reserved
4: // written by Walter Bright
5: // http://www.digitalmars.com
6: // License for redistribution is by either the Artistic License
7: // in artistic.txt, or the GNU General Public License in gnu.txt.
8: // See the included readme.txt for details.
9:
10: #include <stdio.h>
11:
12: static char __file__[] = __FILE__; /* for tassert.h */
13: #include "tassert.h"
14:
15: #include "rmem.h"
16:
17: #include "expression.h"
18: #include "mtype.h"
19: #include "utf.h"
20: #include "declaration.h"
21: #include "aggregate.h"
22: #include "scope.h"
23:
24: //#define DUMP .dump(__PRETTY_FUNCTION__, this)
25: #define DUMP
26:
27: /* ==================== implicitCast ====================== */
28:
29: /**************************************
30: * Do an implicit cast.
31: * Issue error if it can't be done.
32: */
33:
34: Expression *Expression::implicitCastTo(Scope *sc, Type *t)
35: {
36: //printf("Expression::implicitCastTo(%s of type %s) => %s\n", toChars(), type->toChars(), t->toChars());
37:
38: MATCH match = implicitConvTo(t);
39: if (match)
40: { TY tyfrom = type->toBasetype()->ty;
41: TY tyto = t->toBasetype()->ty;
42: #if DMDV1
43: if (global.params.warnings &&
44: Type::impcnvWarn[tyfrom][tyto] &&
45: op != TOKint64)
46: {
47: Expression *e = optimize(WANTflags | WANTvalue);
48:
49: if (e->op == TOKint64)
50: return e->implicitCastTo(sc, t);
51: if (tyfrom == Tint32 &&
52: (op == TOKadd || op == TOKmin ||
53: op == TOKand || op == TOKor || op == TOKxor)
54: )
55: {
56: /* This is really only a semi-kludge fix,
57: * we really should look at the operands of op
58: * and see if they are narrower types.
59: * For example, b=b|b and b=b|7 and s=b+b should be allowed,
60: * but b=b|i should be an error.
61: */
62: ;
63: }
64: else
65: {
66: warning("implicit conversion of expression (%s) of type %s to %s can cause loss of data",
67: toChars(), type->toChars(), t->toChars());
68: }
69: }
70: #endif
71: #if DMDV2
72: if (match == MATCHconst && t == type->constOf())
73: {
74: Expression *e = copy();
75: e->type = t;
76: return e;
77: }
78: #endif
79: return castTo(sc, t);
80: }
81:
82: Expression *e = optimize(WANTflags | WANTvalue);
83: if (e != this)
84: return e->implicitCastTo(sc, t);
85:
86: #if 0
87: printf("ty = %d\n", type->ty);
88: print();
89: type->print();
90: printf("to:\n");
91: t->print();
92: printf("%p %p type: %s to: %s\n", type->deco, t->deco, type->deco, t->deco);
93: //printf("%p %p %p\n", type->nextOf()->arrayOf(), type, t);
94: fflush(stdout);
95: #endif
96: if (t->ty != Terror && type->ty != Terror)
97: {
98: if (!t->deco)
99: { /* Can happen with:
100: * enum E { One }
101: * class A
102: * { static void fork(EDG dg) { dg(E.One); }
103: * alias void delegate(E) EDG;
104: * }
105: * Should eventually make it work.
106: */
107: error("forward reference to type %s", t->toChars());
108: }
109: else if (t->reliesOnTident())
110: error("forward reference to type %s", t->reliesOnTident()->toChars());
111:
112: error("cannot implicitly convert expression (%s) of type %s to %s",
113: toChars(), type->toChars(), t->toChars());
114: }
115: return new ErrorExp();
116: }
117:
118: Expression *StringExp::implicitCastTo(Scope *sc, Type *t)
119: {
120: //printf("StringExp::implicitCastTo(%s of type %s) => %s\n", toChars(), type->toChars(), t->toChars());
121: unsigned char committed = this->committed;
122: Expression *e = Expression::implicitCastTo(sc, t);
123: if (e->op == TOKstring)
124: {
125: // Retain polysemous nature if it started out that way
126: ((StringExp *)e)->committed = committed;
127: }
128: return e;
129: }
130:
131: Expression *ErrorExp::implicitCastTo(Scope *sc, Type *t)
132: {
133: return this;
134: }
135:
136: /*******************************************
137: * Return !=0 if we can implicitly convert this to type t.
138: * Don't do the actual cast.
139: */
140:
141: MATCH Expression::implicitConvTo(Type *t)
142: {
143: #if 0
144: printf("Expression::implicitConvTo(this=%s, type=%s, t=%s)\n",
145: toChars(), type->toChars(), t->toChars());
146: #endif
147: //static int nest; if (++nest == 10) halt();
148: if (!type)
149: { error("%s is not an expression", toChars());
150: type = Type::terror;
151: }
152: Expression *e = optimize(WANTvalue | WANTflags);
153: if (e->type == t)
154: return MATCHexact;
155: if (e != this)
156: { //printf("\toptimized to %s of type %s\n", e->toChars(), e->type->toChars());
157: return e->implicitConvTo(t);
158: }
159: MATCH match = type->implicitConvTo(t);
160: if (match != MATCHnomatch)
161: return match;
162:
163: /* See if we can do integral narrowing conversions
164: */
165: if (type->isintegral() && t->isintegral() &&
166: type->isTypeBasic() && t->isTypeBasic())
167: { IntRange src = this->getIntRange() DUMP;
168: IntRange targetUnsigned = IntRange::fromType(t, /*isUnsigned*/true) DUMP;
169: IntRange targetSigned = IntRange::fromType(t, /*isUnsigned*/false) DUMP;
170: if (targetUnsigned.contains(src) || targetSigned.contains(src))
171: return MATCHconvert;
172: }
173:
174: #if 0
175: Type *tb = t->toBasetype();
176: if (tb->ty == Tdelegate)
177: { TypeDelegate *td = (TypeDelegate *)tb;
178: TypeFunction *tf = (TypeFunction *)td->nextOf();
179:
180: if (!tf->varargs &&
181: !(tf->arguments && tf->arguments->dim)
182: )
183: {
184: match = type->implicitConvTo(tf->nextOf());
185: if (match)
186: return match;
187: if (tf->nextOf()->toBasetype()->ty == Tvoid)
188: return MATCHconvert;
189: }
190: }
191: #endif
192: return MATCHnomatch;
193: }
194:
195:
196: MATCH IntegerExp::implicitConvTo(Type *t)
197: {
198: #if 0
199: printf("IntegerExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
200: toChars(), type->toChars(), t->toChars());
201: #endif
202: MATCH m = type->implicitConvTo(t);
203: if (m >= MATCHconst)
204: return m;
205:
206: TY ty = type->toBasetype()->ty;
207: TY toty = t->toBasetype()->ty;
208:
209: if (m == MATCHnomatch && t->ty == Tenum)
210: goto Lno;
211:
212: switch (ty)
213: {
214: case Tbool:
215: value &= 1;
216: ty = Tint32;
217: break;
218:
219: case Tint8:
220: value = (signed char)value;
221: ty = Tint32;
222: break;
223:
224: case Tchar:
225: case Tuns8:
226: value &= 0xFF;
227: ty = Tint32;
228: break;
229:
230: case Tint16:
231: value = (short)value;
232: ty = Tint32;
233: break;
234:
235: case Tuns16:
236: case Twchar:
237: value &= 0xFFFF;
238: ty = Tint32;
239: break;
240:
241: case Tint32:
242: value = (int)value;
243: break;
244:
245: case Tuns32:
246: case Tdchar:
247: value &= 0xFFFFFFFF;
248: ty = Tuns32;
249: break;
250:
251: default:
252: break;
253: }
254:
255: // Only allow conversion if no change in value
256: switch (toty)
257: {
258: case Tbool:
259: if ((value & 1) != value)
260: goto Lno;
261: goto Lyes;
262:
263: case Tint8:
264: if ((signed char)value != value)
265: goto Lno;
266: goto Lyes;
267:
268: case Tchar:
269: case Tuns8:
270: //printf("value = %llu %llu\n", (dinteger_t)(unsigned char)value, value);
271: if ((unsigned char)value != value)
272: goto Lno;
273: goto Lyes;
274:
275: case Tint16:
276: if ((short)value != value)
277: goto Lno;
278: goto Lyes;
279:
280: case Tuns16:
281: if ((unsigned short)value != value)
282: goto Lno;
283: goto Lyes;
284:
285: case Tint32:
286: if (ty == Tuns32)
287: {
288: }
289: else if ((int)value != value)
290: goto Lno;
291: goto Lyes;
292:
293: case Tuns32:
294: if (ty == Tint32)
295: {
296: }
297: else if ((unsigned)value != value)
298: goto Lno;
299: goto Lyes;
300:
301: case Tdchar:
302: if (value > 0x10FFFFUL)
303: goto Lno;
304: goto Lyes;
305:
306: case Twchar:
307: if ((unsigned short)value != value)
308: goto Lno;
309: goto Lyes;
310:
311: case Tfloat32:
312: {
313: volatile float f;
314: if (type->isunsigned())
315: {
316: f = (float)value;
317: if (f != value)
318: goto Lno;
319: }
320: else
321: {
322: f = (float)(long long)value;
323: if (f != (long long)value)
324: goto Lno;
325: }
326: goto Lyes;
327: }
328:
329: case Tfloat64:
330: {
331: volatile double f;
332: if (type->isunsigned())
333: {
334: f = (double)value;
335: if (f != value)
336: goto Lno;
337: }
338: else
339: {
340: f = (double)(long long)value;
341: if (f != (long long)value)
342: goto Lno;
343: }
344: goto Lyes;
345: }
346:
347: case Tfloat80:
348: {
349: volatile long double f;
350: if (type->isunsigned())
351: {
352: f = (long double)value;
353: if (f != value)
354: goto Lno;
355: }
356: else
357: {
358: f = (long double)(long long)value;
359: if (f != (long long)value)
360: goto Lno;
361: }
362: goto Lyes;
363: }
364:
365: case Tpointer:
366: //printf("type = %s\n", type->toBasetype()->toChars());
367: //printf("t = %s\n", t->toBasetype()->toChars());
368: if (ty == Tpointer &&
369: type->toBasetype()->nextOf()->ty == t->toBasetype()->nextOf()->ty)
370: { /* Allow things like:
371: * const char* P = cast(char *)3;
372: * char* q = P;
373: */
374: goto Lyes;
375: }
376: break;
377: }
378: return Expression::implicitConvTo(t);
379:
380: Lyes:
381: //printf("MATCHconvert\n");
382: return MATCHconvert;
383:
384: Lno:
385: //printf("MATCHnomatch\n");
386: return MATCHnomatch;
387: }
388:
389: MATCH NullExp::implicitConvTo(Type *t)
390: {
391: #if 0
392: printf("NullExp::implicitConvTo(this=%s, type=%s, t=%s, committed = %d)\n",
393: toChars(), type->toChars(), t->toChars(), committed);
394: #endif
395: if (this->type->equals(t))
396: return MATCHexact;
397:
398: /* Allow implicit conversions from invariant to mutable|const,
399: * and mutable to invariant. It works because, after all, a null
400: * doesn't actually point to anything.
401: */
402: if (t->invariantOf()->equals(type->invariantOf()))
403: return MATCHconst;
404:
405: // NULL implicitly converts to any pointer type or dynamic array
406: if (type->ty == Tpointer && type->nextOf()->ty == Tvoid)
407: {
408: if (t->ty == Ttypedef)
409: t = ((TypeTypedef *)t)->sym->basetype;
410: if (t->ty == Tpointer || t->ty == Tarray ||
411: t->ty == Taarray || t->ty == Tclass ||
412: t->ty == Tdelegate)
413: return committed ? MATCHconvert : MATCHexact;
414: }
415: return Expression::implicitConvTo(t);
416: }
417:
418: #if DMDV2
419: MATCH StructLiteralExp::implicitConvTo(Type *t)
420: {
421: #if 0
422: printf("StructLiteralExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
423: toChars(), type->toChars(), t->toChars());
424: #endif
425: MATCH m = Expression::implicitConvTo(t);
426: if (m != MATCHnomatch)
427: return m;
428: if (type->ty == t->ty && type->ty == Tstruct &&
429: ((TypeStruct *)type)->sym == ((TypeStruct *)t)->sym)
430: {
431: m = MATCHconst;
432: for (int i = 0; i < elements->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
433: { Expression *e = elements->tdata()[i];
434: Type *te = e->type;
435: te = te->castMod(t->mod);
436: MATCH m2 = e->implicitConvTo(te);
437: //printf("\t%s => %s, match = %d\n", e->toChars(), te->toChars(), m2);
438: if (m2 < m)
439: m = m2;
440: }
441: }
442: return m;
443: }
444: #endif
445:
446: MATCH StringExp::implicitConvTo(Type *t)
447: { MATCH m;
warning C4101: 'm' : unreferenced local variable
448:
449: #if 0
450: printf("StringExp::implicitConvTo(this=%s, committed=%d, type=%s, t=%s)\n",
451: toChars(), committed, type->toChars(), t->toChars());
452: #endif
453: if (!committed && t->ty == Tpointer && t->nextOf()->ty == Tvoid)
454: {
455: return MATCHnomatch;
456: }
457: if (type->ty == Tsarray || type->ty == Tarray || type->ty == Tpointer)
458: {
459: TY tyn = type->nextOf()->ty;
460: if (tyn == Tchar || tyn == Twchar || tyn == Tdchar)
461: { Type *tn;
462: MATCH m;
warning C6246: Local declaration of 'm' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '447' of 'c:\projects\extern\d\dmd\src\cast.c': Lines: 447
463:
464: switch (t->ty)
465: {
466: case Tsarray:
467: if (type->ty == Tsarray)
468: {
469: if (((TypeSArray *)type)->dim->toInteger() !=
470: ((TypeSArray *)t)->dim->toInteger())
471: return MATCHnomatch;
472: TY tynto = t->nextOf()->ty;
473: if (tynto == tyn)
474: return MATCHexact;
475: if (!committed && (tynto == Tchar || tynto == Twchar || tynto == Tdchar))
476: return MATCHexact;
477: }
478: else if (type->ty == Tarray)
479: {
480: if (length() >
481: ((TypeSArray *)t)->dim->toInteger())
482: return MATCHnomatch;
483: TY tynto = t->nextOf()->ty;
484: if (tynto == tyn)
485: return MATCHexact;
486: if (!committed && (tynto == Tchar || tynto == Twchar || tynto == Tdchar))
487: return MATCHexact;
488: }
489: case Tarray:
490: case Tpointer:
491: tn = t->nextOf();
492: m = MATCHexact;
493: if (type->nextOf()->mod != tn->mod)
494: { if (!tn->isConst())
495: return MATCHnomatch;
496: m = MATCHconst;
497: }
498: switch (tn->ty)
499: {
500: case Tchar:
501: case Twchar:
502: case Tdchar:
503: if (!committed)
504: return m;
505: break;
506: }
507: break;
508: }
509: }
510: }
511: return Expression::implicitConvTo(t);
512: #if 0
513: m = (MATCH)type->implicitConvTo(t);
514: if (m)
515: {
516: return m;
517: }
518:
519: return MATCHnomatch;
520: #endif
521: }
522:
523: MATCH ArrayLiteralExp::implicitConvTo(Type *t)
524: { MATCH result = MATCHexact;
525:
526: #if 0
527: printf("ArrayLiteralExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
528: toChars(), type->toChars(), t->toChars());
529: #endif
530: Type *typeb = type->toBasetype();
531: Type *tb = t->toBasetype();
532: if ((tb->ty == Tarray || tb->ty == Tsarray) &&
533: (typeb->ty == Tarray || typeb->ty == Tsarray))
534: {
535: if (tb->ty == Tsarray)
536: { TypeSArray *tsa = (TypeSArray *)tb;
537: if (elements->dim != tsa->dim->toInteger())
538: result = MATCHnomatch;
539: }
540:
541: for (int i = 0; i < elements->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
542: { Expression *e = elements->tdata()[i];
543: MATCH m = (MATCH)e->implicitConvTo(tb->nextOf());
544: if (m < result)
545: result = m; // remember worst match
546: if (result == MATCHnomatch)
547: break; // no need to check for worse
548: }
549: return result;
550: }
551: else
552: return Expression::implicitConvTo(t);
553: }
554:
555: MATCH AssocArrayLiteralExp::implicitConvTo(Type *t)
556: { MATCH result = MATCHexact;
557:
558: Type *typeb = type->toBasetype();
559: Type *tb = t->toBasetype();
560: if (tb->ty == Taarray && typeb->ty == Taarray)
561: {
562: for (size_t i = 0; i < keys->dim; i++)
563: { Expression *e = keys->tdata()[i];
564: MATCH m = (MATCH)e->implicitConvTo(((TypeAArray *)tb)->index);
565: if (m < result)
566: result = m; // remember worst match
567: if (result == MATCHnomatch)
568: break; // no need to check for worse
569: e = values->tdata()[i];
570: m = (MATCH)e->implicitConvTo(tb->nextOf());
571: if (m < result)
572: result = m; // remember worst match
573: if (result == MATCHnomatch)
574: break; // no need to check for worse
575: }
576: return result;
577: }
578: else
579: return Expression::implicitConvTo(t);
580: }
581:
582: MATCH AddrExp::implicitConvTo(Type *t)
583: {
584: #if 0
585: printf("AddrExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
586: toChars(), type->toChars(), t->toChars());
587: #endif
588: MATCH result;
589:
590: result = type->implicitConvTo(t);
591: //printf("\tresult = %d\n", result);
592:
593: if (result == MATCHnomatch)
594: {
595: // Look for pointers to functions where the functions are overloaded.
596:
597: t = t->toBasetype();
598:
599: if (e1->op == TOKoverloadset &&
600: (t->ty == Tpointer || t->ty == Tdelegate) && t->nextOf()->ty == Tfunction)
601: { OverExp *eo = (OverExp *)e1;
602: FuncDeclaration *f = NULL;
603: for (int i = 0; i < eo->vars->a.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
604: { Dsymbol *s = eo->vars->a.tdata()[i];
605: FuncDeclaration *f2 = s->isFuncDeclaration();
606: assert(f2);
607: if (f2->overloadExactMatch(t->nextOf()))
608: { if (f)
609: /* Error if match in more than one overload set,
610: * even if one is a 'better' match than the other.
611: */
612: ScopeDsymbol::multiplyDefined(loc, f, f2);
613: else
614: f = f2;
615: result = MATCHexact;
616: }
617: }
618: }
619:
620: if (type->ty == Tpointer && type->nextOf()->ty == Tfunction &&
621: t->ty == Tpointer && t->nextOf()->ty == Tfunction &&
622: e1->op == TOKvar)
623: {
624: /* I don't think this can ever happen -
625: * it should have been
626: * converted to a SymOffExp.
627: */
628: assert(0);
629: VarExp *ve = (VarExp *)e1;
630: FuncDeclaration *f = ve->var->isFuncDeclaration();
631: if (f && f->overloadExactMatch(t->nextOf()))
632: result = MATCHexact;
633: }
634: }
635: //printf("\tresult = %d\n", result);
636: return result;
637: }
638:
639: MATCH SymOffExp::implicitConvTo(Type *t)
640: {
641: #if 0
642: printf("SymOffExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
643: toChars(), type->toChars(), t->toChars());
644: #endif
645: MATCH result;
646:
647: result = type->implicitConvTo(t);
648: //printf("\tresult = %d\n", result);
649:
650: if (result == MATCHnomatch)
651: {
652: // Look for pointers to functions where the functions are overloaded.
653: FuncDeclaration *f;
654:
655: t = t->toBasetype();
656: if (type->ty == Tpointer && type->nextOf()->ty == Tfunction &&
657: (t->ty == Tpointer || t->ty == Tdelegate) && t->nextOf()->ty == Tfunction)
658: {
659: f = var->isFuncDeclaration();
660: if (f)
661: { f = f->overloadExactMatch(t->nextOf());
662: if (f)
663: { if ((t->ty == Tdelegate && (f->needThis() || f->isNested())) ||
664: (t->ty == Tpointer && !(f->needThis() || f->isNested())))
665: {
666: result = MATCHexact;
667: }
668: }
669: }
670: }
671: }
672: //printf("\tresult = %d\n", result);
673: return result;
674: }
675:
676: MATCH DelegateExp::implicitConvTo(Type *t)
677: {
678: #if 0
679: printf("DelegateExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
680: toChars(), type->toChars(), t->toChars());
681: #endif
682: MATCH result;
683:
684: result = type->implicitConvTo(t);
685:
686: if (result == MATCHnomatch)
687: {
688: // Look for pointers to functions where the functions are overloaded.
689: FuncDeclaration *f;
warning C4101: 'f' : unreferenced local variable
690:
691: t = t->toBasetype();
692: if (type->ty == Tdelegate && type->nextOf()->ty == Tfunction &&
693: t->ty == Tdelegate && t->nextOf()->ty == Tfunction)
694: {
695: if (func && func->overloadExactMatch(t->nextOf()))
696: result = MATCHexact;
697: }
698: }
699: return result;
700: }
701:
702: MATCH OrExp::implicitConvTo(Type *t)
703: {
704: MATCH result = Expression::implicitConvTo(t);
705:
706: if (result == MATCHnomatch)
707: {
708: MATCH m1 = e1->implicitConvTo(t);
709: MATCH m2 = e2->implicitConvTo(t);
710:
711: // Pick the worst match
712: result = (m1 < m2) ? m1 : m2;
713: }
714: return result;
715: }
716:
717: MATCH XorExp::implicitConvTo(Type *t)
718: {
719: MATCH result = Expression::implicitConvTo(t);
720:
721: if (result == MATCHnomatch)
722: {
723: MATCH m1 = e1->implicitConvTo(t);
724: MATCH m2 = e2->implicitConvTo(t);
725:
726: // Pick the worst match
727: result = (m1 < m2) ? m1 : m2;
728: }
729: return result;
730: }
731:
732: MATCH CondExp::implicitConvTo(Type *t)
733: {
734: MATCH m1 = e1->implicitConvTo(t);
735: MATCH m2 = e2->implicitConvTo(t);
736: //printf("CondExp: m1 %d m2 %d\n", m1, m2);
737:
738: // Pick the worst match
739: return (m1 < m2) ? m1 : m2;
740: }
741:
742: MATCH CommaExp::implicitConvTo(Type *t)
743: {
744: return e2->implicitConvTo(t);
745: }
746:
747: MATCH CastExp::implicitConvTo(Type *t)
748: {
749: #if 0
750: printf("CastExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
751: toChars(), type->toChars(), t->toChars());
752: #endif
753: MATCH result;
754:
755: result = type->implicitConvTo(t);
756:
757: if (result == MATCHnomatch)
758: {
759: if (t->isintegral() &&
760: e1->type->isintegral() &&
761: e1->implicitConvTo(t) != MATCHnomatch)
762: result = MATCHconvert;
763: else
764: result = Expression::implicitConvTo(t);
765: }
766: return result;
767: }
768:
769: /* ==================== castTo ====================== */
770:
771: /**************************************
772: * Do an explicit cast.
773: */
774:
775: Expression *Expression::castTo(Scope *sc, Type *t)
776: {
777: //printf("Expression::castTo(this=%s, t=%s)\n", toChars(), t->toChars());
778: #if 0
779: printf("Expression::castTo(this=%s, type=%s, t=%s)\n",
780: toChars(), type->toChars(), t->toChars());
781: #endif
782: if (type == t)
783: return this;
784: Expression *e = this;
785: Type *tb = t->toBasetype();
786: Type *typeb = type->toBasetype();
787: if (tb != typeb)
788: {
789: // Do (type *) cast of (type [dim])
790: if (tb->ty == Tpointer &&
791: typeb->ty == Tsarray
792: )
793: {
794: //printf("Converting [dim] to *\n");
795:
796: if (typeb->size(loc) == 0)
797: e = new NullExp(loc);
798: else
799: e = new AddrExp(loc, e);
800: }
801: #if 0
802: else if (tb->ty == Tdelegate && type->ty != Tdelegate)
803: {
804: TypeDelegate *td = (TypeDelegate *)tb;
805: TypeFunction *tf = (TypeFunction *)td->nextOf();
806: return toDelegate(sc, tf->nextOf());
807: }
808: #endif
809: else
810: {
811: if (typeb->ty == Tstruct)
812: { TypeStruct *ts = (TypeStruct *)typeb;
813: if (!(tb->ty == Tstruct && ts->sym == ((TypeStruct *)tb)->sym) &&
814: ts->sym->aliasthis)
815: { /* Forward the cast to our alias this member, rewrite to:
816: * cast(to)e1.aliasthis
817: */
818: Expression *e1 = new DotIdExp(loc, this, ts->sym->aliasthis->ident);
819: Expression *e = new CastExp(loc, e1, tb);
warning C6246: Local declaration of 'e' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '784' of 'c:\projects\extern\d\dmd\src\cast.c': Lines: 784
820: e = e->semantic(sc);
821: return e;
822: }
823: }
824: else if (typeb->ty == Tclass)
825: { TypeClass *ts = (TypeClass *)typeb;
826: if (ts->sym->aliasthis)
827: {
828: if (tb->ty == Tclass)
829: {
830: ClassDeclaration *cdfrom = typeb->isClassHandle();
831: ClassDeclaration *cdto = tb->isClassHandle();
832: int offset;
833: if (cdto->isBaseOf(cdfrom, &offset))
834: goto L1;
835: }
836: /* Forward the cast to our alias this member, rewrite to:
837: * cast(to)e1.aliasthis
838: */
839: Expression *e1 = new DotIdExp(loc, this, ts->sym->aliasthis->ident);
840: Expression *e = new CastExp(loc, e1, tb);
warning C6246: Local declaration of 'e' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '784' of 'c:\projects\extern\d\dmd\src\cast.c': Lines: 784
841: e = e->semantic(sc);
842: return e;
843: }
844: L1: ;
845: }
846: e = new CastExp(loc, e, tb);
847: }
848: }
849: else
850: {
851: e = e->copy(); // because of COW for assignment to e->type
852: }
853: assert(e != this);
854: e->type = t;
855: //printf("Returning: %s\n", e->toChars());
856: return e;
857: }
858:
859:
860: Expression *ErrorExp::castTo(Scope *sc, Type *t)
861: {
862: return this;
863: }
864:
865:
866: Expression *RealExp::castTo(Scope *sc, Type *t)
867: { Expression *e = this;
868: if (type != t)
869: {
870: if ((type->isreal() && t->isreal()) ||
871: (type->isimaginary() && t->isimaginary())
872: )
873: { e = copy();
874: e->type = t;
875: }
876: else
877: e = Expression::castTo(sc, t);
878: }
879: return e;
880: }
881:
882:
883: Expression *ComplexExp::castTo(Scope *sc, Type *t)
884: { Expression *e = this;
885: if (type != t)
886: {
887: if (type->iscomplex() && t->iscomplex())
888: { e = copy();
889: e->type = t;
890: }
891: else
892: e = Expression::castTo(sc, t);
893: }
894: return e;
895: }
896:
897:
898: Expression *NullExp::castTo(Scope *sc, Type *t)
899: { NullExp *e;
900: Type *tb;
901:
902: //printf("NullExp::castTo(t = %p)\n", t);
903: if (type == t)
904: {
905: committed = 1;
906: return this;
907: }
908: e = (NullExp *)copy();
909: e->committed = 1;
910: tb = t->toBasetype();
911: e->type = type->toBasetype();
912: if (tb != e->type)
913: {
914: // NULL implicitly converts to any pointer type or dynamic array
915: if (e->type->ty == Tpointer && e->type->nextOf()->ty == Tvoid &&
916: (tb->ty == Tpointer || tb->ty == Tarray || tb->ty == Taarray ||
917: tb->ty == Tdelegate))
918: {
919: #if 0
920: if (tb->ty == Tdelegate)
921: { TypeDelegate *td = (TypeDelegate *)tb;
922: TypeFunction *tf = (TypeFunction *)td->nextOf();
923:
924: if (!tf->varargs &&
925: !(tf->arguments && tf->arguments->dim)
926: )
927: {
928: return Expression::castTo(sc, t);
929: }
930: }
931: #endif
932: }
933: else
934: {
935: return e->Expression::castTo(sc, t);
936: }
937: }
938: e->type = t;
939: return e;
940: }
941:
942: Expression *StringExp::castTo(Scope *sc, Type *t)
943: {
944: /* This follows copy-on-write; any changes to 'this'
945: * will result in a copy.
946: * The this->string member is considered immutable.
947: */
948: int copied = 0;
949:
950: //printf("StringExp::castTo(t = %s), '%s' committed = %d\n", t->toChars(), toChars(), committed);
951:
952: if (!committed && t->ty == Tpointer && t->nextOf()->ty == Tvoid)
953: {
954: error("cannot convert string literal to void*");
955: return new ErrorExp();
956: }
957:
958: StringExp *se = this;
959: if (!committed)
960: { se = (StringExp *)copy();
961: se->committed = 1;
962: copied = 1;
963: }
964:
965: if (type == t)
966: {
967: return se;
968: }
969:
970: Type *tb = t->toBasetype();
971: //printf("\ttype = %s\n", type->toChars());
972: if (tb->ty == Tdelegate && type->toBasetype()->ty != Tdelegate)
973: return Expression::castTo(sc, t);
974:
975: Type *typeb = type->toBasetype();
976: if (typeb == tb)
977: {
978: if (!copied)
979: { se = (StringExp *)copy();
980: copied = 1;
981: }
982: se->type = t;
983: return se;
984: }
985:
986: if (committed && tb->ty == Tsarray && typeb->ty == Tarray)
987: {
988: se = (StringExp *)copy();
989: se->sz = tb->nextOf()->size();
warning C4244: '=' : conversion from 'd_uns64' to 'unsigned char', possible loss of data
990: se->len = (len * sz) / se->sz;
991: se->committed = 1;
992: se->type = t;
993: return se;
994: }
995:
996: if (tb->ty != Tsarray && tb->ty != Tarray && tb->ty != Tpointer)
997: { if (!copied)
998: { se = (StringExp *)copy();
999: copied = 1;
1000: }
1001: goto Lcast;
1002: }
1003: if (typeb->ty != Tsarray && typeb->ty != Tarray && typeb->ty != Tpointer)
1004: { if (!copied)
1005: { se = (StringExp *)copy();
1006: copied = 1;
1007: }
1008: goto Lcast;
1009: }
1010:
1011: if (typeb->nextOf()->size() == tb->nextOf()->size())
1012: {
1013: if (!copied)
1014: { se = (StringExp *)copy();
1015: copied = 1;
1016: }
1017: if (tb->ty == Tsarray)
1018: goto L2; // handle possible change in static array dimension
1019: se->type = t;
1020: return se;
1021: }
1022:
1023: if (committed)
1024: goto Lcast;
1025:
1026: #define X(tf,tt) ((tf) * 256 + (tt))
1027: {
1028: OutBuffer buffer;
1029: size_t newlen = 0;
1030: int tfty = typeb->nextOf()->toBasetype()->ty;
1031: int ttty = tb->nextOf()->toBasetype()->ty;
1032: switch (X(tfty, ttty))
1033: {
1034: case X(Tchar, Tchar):
1035: case X(Twchar,Twchar):
1036: case X(Tdchar,Tdchar):
1037: break;
1038:
1039: case X(Tchar, Twchar):
1040: for (size_t u = 0; u < len;)
1041: { unsigned c;
1042: const char *p = utf_decodeChar((unsigned char *)se->string, len, &u, &c);
1043: if (p)
1044: error("%s", p);
1045: else
1046: buffer.writeUTF16(c);
1047: }
1048: newlen = buffer.offset / 2;
1049: buffer.writeUTF16(0);
1050: goto L1;
1051:
1052: case X(Tchar, Tdchar):
1053: for (size_t u = 0; u < len;)
1054: { unsigned c;
1055: const char *p = utf_decodeChar((unsigned char *)se->string, len, &u, &c);
1056: if (p)
1057: error("%s", p);
1058: buffer.write4(c);
1059: newlen++;
1060: }
1061: buffer.write4(0);
1062: goto L1;
1063:
1064: case X(Twchar,Tchar):
1065: for (size_t u = 0; u < len;)
1066: { unsigned c;
1067: const char *p = utf_decodeWchar((unsigned short *)se->string, len, &u, &c);
1068: if (p)
1069: error("%s", p);
1070: else
1071: buffer.writeUTF8(c);
1072: }
1073: newlen = buffer.offset;
1074: buffer.writeUTF8(0);
1075: goto L1;
1076:
1077: case X(Twchar,Tdchar):
1078: for (size_t u = 0; u < len;)
1079: { unsigned c;
1080: const char *p = utf_decodeWchar((unsigned short *)se->string, len, &u, &c);
1081: if (p)
1082: error("%s", p);
1083: buffer.write4(c);
1084: newlen++;
1085: }
1086: buffer.write4(0);
1087: goto L1;
1088:
1089: case X(Tdchar,Tchar):
1090: for (size_t u = 0; u < len; u++)
1091: {
1092: unsigned c = ((unsigned *)se->string)[u];
1093: if (!utf_isValidDchar(c))
1094: error("invalid UCS-32 char \\U%08x", c);
1095: else
1096: buffer.writeUTF8(c);
1097: newlen++;
1098: }
1099: newlen = buffer.offset;
1100: buffer.writeUTF8(0);
1101: goto L1;
1102:
1103: case X(Tdchar,Twchar):
1104: for (size_t u = 0; u < len; u++)
1105: {
1106: unsigned c = ((unsigned *)se->string)[u];
1107: if (!utf_isValidDchar(c))
1108: error("invalid UCS-32 char \\U%08x", c);
1109: else
1110: buffer.writeUTF16(c);
1111: newlen++;
1112: }
1113: newlen = buffer.offset / 2;
1114: buffer.writeUTF16(0);
1115: goto L1;
1116:
1117: L1:
1118: if (!copied)
1119: { se = (StringExp *)copy();
1120: copied = 1;
1121: }
1122: se->string = buffer.extractData();
1123: se->len = newlen;
1124: se->sz = tb->nextOf()->size();
warning C4244: '=' : conversion from 'd_uns64' to 'unsigned char', possible loss of data
1125: break;
1126:
1127: default:
1128: assert(typeb->nextOf()->size() != tb->nextOf()->size());
1129: goto Lcast;
1130: }
1131: }
1132: #undef X
1133: L2:
1134: assert(copied);
1135:
1136: // See if need to truncate or extend the literal
1137: if (tb->ty == Tsarray)
1138: {
1139: int dim2 = ((TypeSArray *)tb)->dim->toInteger();
warning C4244: 'initializing' : conversion from 'dinteger_t' to 'int', possible loss of data
1140:
1141: //printf("dim from = %d, to = %d\n", se->len, dim2);
1142:
1143: // Changing dimensions
1144: if (dim2 != se->len)
1145: {
1146: // Copy when changing the string literal
1147: unsigned newsz = se->sz;
1148: void *s;
1149: int d;
1150:
1151: d = (dim2 < se->len) ? dim2 : se->len;
warning C4018: '<' : signed/unsigned mismatch
1152: s = (unsigned char *)mem.malloc((dim2 + 1) * newsz);
1153: memcpy(s, se->string, d * newsz);
1154: // Extend with 0, add terminating 0
1155: memset((char *)s + d * newsz, 0, (dim2 + 1 - d) * newsz);
1156: se->string = s;
1157: se->len = dim2;
1158: }
1159: }
1160: se->type = t;
1161: return se;
1162:
1163: Lcast:
1164: Expression *e = new CastExp(loc, se, t);
1165: e->type = t; // so semantic() won't be run on e
1166: return e;
1167: }
1168:
1169: Expression *AddrExp::castTo(Scope *sc, Type *t)
1170: {
1171: Type *tb;
1172:
1173: #if 0
1174: printf("AddrExp::castTo(this=%s, type=%s, t=%s)\n",
1175: toChars(), type->toChars(), t->toChars());
1176: #endif
1177: Expression *e = this;
1178:
1179: tb = t->toBasetype();
1180: type = type->toBasetype();
1181: if (tb != type)
1182: {
1183: // Look for pointers to functions where the functions are overloaded.
1184:
1185: if (e1->op == TOKoverloadset &&
1186: (t->ty == Tpointer || t->ty == Tdelegate) && t->nextOf()->ty == Tfunction)
1187: { OverExp *eo = (OverExp *)e1;
1188: FuncDeclaration *f = NULL;
1189: for (int i = 0; i < eo->vars->a.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1190: { Dsymbol *s = eo->vars->a.tdata()[i];
1191: FuncDeclaration *f2 = s->isFuncDeclaration();
1192: assert(f2);
1193: if (f2->overloadExactMatch(t->nextOf()))
1194: { if (f)
1195: /* Error if match in more than one overload set,
1196: * even if one is a 'better' match than the other.
1197: */
1198: ScopeDsymbol::multiplyDefined(loc, f, f2);
1199: else
1200: f = f2;
1201: }
1202: }
1203: if (f)
1204: { f->tookAddressOf++;
1205: SymOffExp *se = new SymOffExp(loc, f, 0, 0);
1206: se->semantic(sc);
1207: // Let SymOffExp::castTo() do the heavy lifting
1208: return se->castTo(sc, t);
1209: }
1210: }
1211:
1212:
1213: if (type->ty == Tpointer && type->nextOf()->ty == Tfunction &&
1214: tb->ty == Tpointer && tb->nextOf()->ty == Tfunction &&
1215: e1->op == TOKvar)
1216: {
1217: VarExp *ve = (VarExp *)e1;
1218: FuncDeclaration *f = ve->var->isFuncDeclaration();
1219: if (f)
1220: {
1221: assert(0); // should be SymOffExp instead
1222: f = f->overloadExactMatch(tb->nextOf());
1223: if (f)
1224: {
1225: e = new VarExp(loc, f);
1226: e->type = f->type;
1227: e = new AddrExp(loc, e);
1228: e->type = t;
1229: return e;
1230: }
1231: }
1232: }
1233: e = Expression::castTo(sc, t);
1234: }
1235: e->type = t;
1236: return e;
1237: }
1238:
1239:
1240: Expression *TupleExp::castTo(Scope *sc, Type *t)
1241: { TupleExp *e = (TupleExp *)copy();
1242: e->exps = (Expressions *)exps->copy();
1243: for (size_t i = 0; i < e->exps->dim; i++)
1244: { Expression *ex = e->exps->tdata()[i];
1245: ex = ex->castTo(sc, t);
1246: e->exps->tdata()[i] = ex;
1247: }
1248: return e;
1249: }
1250:
1251:
1252: Expression *ArrayLiteralExp::castTo(Scope *sc, Type *t)
1253: {
1254: #if 0
1255: printf("ArrayLiteralExp::castTo(this=%s, type=%s, => %s)\n",
1256: toChars(), type->toChars(), t->toChars());
1257: #endif
1258: if (type == t)
1259: return this;
1260: ArrayLiteralExp *e = this;
1261: Type *typeb = type->toBasetype();
1262: Type *tb = t->toBasetype();
1263: if ((tb->ty == Tarray || tb->ty == Tsarray) &&
1264: (typeb->ty == Tarray || typeb->ty == Tsarray) &&
1265: // Not trying to convert non-void[] to void[]
1266: !(tb->nextOf()->toBasetype()->ty == Tvoid && typeb->nextOf()->toBasetype()->ty != Tvoid))
1267: {
1268: if (tb->ty == Tsarray)
1269: { TypeSArray *tsa = (TypeSArray *)tb;
1270: if (elements->dim != tsa->dim->toInteger())
1271: goto L1;
1272: }
1273:
1274: e = (ArrayLiteralExp *)copy();
1275: e->elements = (Expressions *)elements->copy();
1276: for (int i = 0; i < elements->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1277: { Expression *ex = elements->tdata()[i];
1278: ex = ex->castTo(sc, tb->nextOf());
1279: e->elements->tdata()[i] = ex;
1280: }
1281: e->type = t;
1282: return e;
1283: }
1284: if (tb->ty == Tpointer && typeb->ty == Tsarray)
1285: {
1286: Type *tp = typeb->nextOf()->pointerTo();
1287: if (!tp->equals(e->type))
1288: { e = (ArrayLiteralExp *)copy();
1289: e->type = tp;
1290: }
1291: }
1292: L1:
1293: return e->Expression::castTo(sc, t);
1294: }
1295:
1296: Expression *AssocArrayLiteralExp::castTo(Scope *sc, Type *t)
1297: {
1298: if (type == t)
1299: return this;
1300: AssocArrayLiteralExp *e = this;
1301: Type *typeb = type->toBasetype();
1302: Type *tb = t->toBasetype();
1303: if (tb->ty == Taarray && typeb->ty == Taarray &&
1304: tb->nextOf()->toBasetype()->ty != Tvoid)
1305: {
1306: e = (AssocArrayLiteralExp *)copy();
1307: e->keys = (Expressions *)keys->copy();
1308: e->values = (Expressions *)values->copy();
1309: assert(keys->dim == values->dim);
1310: for (size_t i = 0; i < keys->dim; i++)
1311: { Expression *ex = values->tdata()[i];
1312: ex = ex->castTo(sc, tb->nextOf());
1313: e->values->tdata()[i] = ex;
1314:
1315: ex = keys->tdata()[i];
1316: ex = ex->castTo(sc, ((TypeAArray *)tb)->index);
1317: e->keys->tdata()[i] = ex;
1318: }
1319: e->type = t;
1320: return e;
1321: }
1322: L1:
warning C4102: 'L1' : unreferenced label
1323: return e->Expression::castTo(sc, t);
1324: }
1325:
1326: Expression *SymOffExp::castTo(Scope *sc, Type *t)
1327: {
1328: #if 0
1329: printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n",
1330: toChars(), type->toChars(), t->toChars());
1331: #endif
1332: if (type == t && hasOverloads == 0)
1333: return this;
1334: Expression *e;
1335: Type *tb = t->toBasetype();
1336: Type *typeb = type->toBasetype();
1337: if (tb != typeb)
1338: {
1339: // Look for pointers to functions where the functions are overloaded.
1340: FuncDeclaration *f;
1341:
1342: if (hasOverloads &&
1343: typeb->ty == Tpointer && typeb->nextOf()->ty == Tfunction &&
1344: (tb->ty == Tpointer || tb->ty == Tdelegate) && tb->nextOf()->ty == Tfunction)
1345: {
1346: f = var->isFuncDeclaration();
1347: if (f)
1348: {
1349: f = f->overloadExactMatch(tb->nextOf());
1350: if (f)
1351: {
1352: if (tb->ty == Tdelegate)
1353: {
1354: if (f->needThis() && hasThis(sc))
1355: {
1356: e = new DelegateExp(loc, new ThisExp(loc), f);
1357: e = e->semantic(sc);
1358: }
1359: else if (f->isNested())
1360: {
1361: e = new DelegateExp(loc, new IntegerExp(0), f);
1362: e = e->semantic(sc);
1363: }
1364: else if (f->needThis())
1365: { error("no 'this' to create delegate for %s", f->toChars());
1366: return new ErrorExp();
1367: }
1368: else
1369: { error("cannot cast from function pointer to delegate");
1370: return new ErrorExp();
1371: }
1372: }
1373: else
1374: {
1375: e = new SymOffExp(loc, f, 0);
1376: e->type = t;
1377: }
1378: #if DMDV2
1379: f->tookAddressOf++;
1380: #endif
1381: return e;
1382: }
1383: }
1384: }
1385: e = Expression::castTo(sc, t);
1386: }
1387: else
1388: { e = copy();
1389: e->type = t;
1390: ((SymOffExp *)e)->hasOverloads = 0;
1391: }
1392: return e;
1393: }
1394:
1395: Expression *DelegateExp::castTo(Scope *sc, Type *t)
1396: {
1397: #if 0
1398: printf("DelegateExp::castTo(this=%s, type=%s, t=%s)\n",
1399: toChars(), type->toChars(), t->toChars());
1400: #endif
1401: static char msg[] = "cannot form delegate due to covariant return type";
1402:
1403: Expression *e = this;
1404: Type *tb = t->toBasetype();
1405: Type *typeb = type->toBasetype();
1406: if (tb != typeb)
1407: {
1408: // Look for delegates to functions where the functions are overloaded.
1409: FuncDeclaration *f;
1410:
1411: if (typeb->ty == Tdelegate && typeb->nextOf()->ty == Tfunction &&
1412: tb->ty == Tdelegate && tb->nextOf()->ty == Tfunction)
1413: {
1414: if (func)
1415: {
1416: f = func->overloadExactMatch(tb->nextOf());
1417: if (f)
1418: { int offset;
1419: if (f->tintro && f->tintro->nextOf()->isBaseOf(f->type->nextOf(), &offset) && offset)
1420: error("%s", msg);
1421: f->tookAddressOf++;
1422: e = new DelegateExp(loc, e1, f);
1423: e->type = t;
1424: return e;
1425: }
1426: if (func->tintro)
1427: error("%s", msg);
1428: }
1429: }
1430: e = Expression::castTo(sc, t);
1431: }
1432: else
1433: { int offset;
1434:
1435: func->tookAddressOf++;
1436: if (func->tintro && func->tintro->nextOf()->isBaseOf(func->type->nextOf(), &offset) && offset)
1437: error("%s", msg);
1438: e = copy();
1439: e->type = t;
1440: }
1441: return e;
1442: }
1443:
1444: Expression *CondExp::castTo(Scope *sc, Type *t)
1445: {
1446: Expression *e = this;
1447:
1448: if (type != t)
1449: {
1450: if (1 || e1->op == TOKstring || e2->op == TOKstring)
warning C6235: (<non-zero constant> || <expression>) is always a non-zero constant
1451: { e = new CondExp(loc, econd, e1->castTo(sc, t), e2->castTo(sc, t));
1452: e->type = t;
1453: }
1454: else
1455: e = Expression::castTo(sc, t);
1456: }
1457: return e;
1458: }
1459:
1460: Expression *CommaExp::castTo(Scope *sc, Type *t)
1461: {
1462: Expression *e2c = e2->castTo(sc, t);
1463: Expression *e;
1464:
1465: if (e2c != e2)
1466: {
1467: e = new CommaExp(loc, e1, e2c);
1468: e->type = e2c->type;
1469: }
1470: else
1471: { e = this;
1472: e->type = e2->type;
1473: }
1474: return e;
1475: }
1476:
1477: /* ==================== ====================== */
1478:
1479: /****************************************
1480: * Scale addition/subtraction to/from pointer.
1481: */
1482:
1483: Expression *BinExp::scaleFactor(Scope *sc)
1484: {
1485: if (sc->func && !sc->intypeof)
1486: {
1487: if (sc->func->setUnsafe())
1488: {
1489: error("pointer arithmetic not allowed in @safe functions");
1490: return new ErrorExp();
1491: }
1492: }
1493:
1494: d_uns64 stride;
1495: Type *t1b = e1->type->toBasetype();
1496: Type *t2b = e2->type->toBasetype();
1497:
1498: if (t1b->ty == Tpointer && t2b->isintegral())
1499: { // Need to adjust operator by the stride
1500: // Replace (ptr + int) with (ptr + (int * stride))
1501: Type *t = Type::tptrdiff_t;
1502:
1503: stride = t1b->nextOf()->size(loc);
1504: if (!t->equals(t2b))
1505: e2 = e2->castTo(sc, t);
1506: e2 = new MulExp(loc, e2, new IntegerExp(0, stride, t));
1507: e2->type = t;
1508: type = e1->type;
1509: }
1510: else if (t2b->ty == Tpointer && t1b->isintegral())
1511: { // Need to adjust operator by the stride
1512: // Replace (int + ptr) with (ptr + (int * stride))
1513: Type *t = Type::tptrdiff_t;
1514: Expression *e;
1515:
1516: stride = t2b->nextOf()->size(loc);
1517: if (!t->equals(t1b))
1518: e = e1->castTo(sc, t);
1519: else
1520: e = e1;
1521: e = new MulExp(loc, e, new IntegerExp(0, stride, t));
1522: e->type = t;
1523: type = e2->type;
1524: e1 = e2;
1525: e2 = e;
1526: }
1527: return this;
1528: }
1529:
1530: /**************************************
1531: * Return true if e is an empty array literal with dimensionality
1532: * equal to or less than type of other array.
1533: * [], [[]], [[[]]], etc.
1534: * I.e., make sure that [1,2] is compatible with [],
1535: * [[1,2]] is compatible with [[]], etc.
1536: */
1537: bool isVoidArrayLiteral(Expression *e, Type *other)
1538: {
1539: while (e->op == TOKarrayliteral && e->type->ty == Tarray
1540: && (((ArrayLiteralExp *)e)->elements->dim == 1))
1541: {
1542: e = ((ArrayLiteralExp *)e)->elements->tdata()[0];
1543: if (other->ty == Tsarray || other->ty == Tarray)
1544: other = other->nextOf();
1545: else
1546: return false;
1547: }
1548: if (other->ty != Tsarray && other->ty != Tarray)
1549: return false;
1550: Type *t = e->type;
1551: return (e->op == TOKarrayliteral && t->ty == Tarray &&
1552: t->nextOf()->ty == Tvoid &&
1553: ((ArrayLiteralExp *)e)->elements->dim == 0);
1554: }
1555:
1556:
1557: /**************************************
1558: * Combine types.
1559: * Output:
1560: * *pt merged type, if *pt is not NULL
1561: * *pe1 rewritten e1
1562: * *pe2 rewritten e2
1563: * Returns:
1564: * !=0 success
1565: * 0 failed
1566: */
1567:
1568: int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression **pe2)
1569: {
1570: //printf("typeMerge() %s op %s\n", (*pe1)->toChars(), (*pe2)->toChars());
1571: //e->dump(0);
1572:
1573: Expression *e1 = *pe1;
1574: Expression *e2 = *pe2;
1575:
1576: if (e->op != TOKquestion ||
1577: e1->type->toBasetype()->ty != e2->type->toBasetype()->ty)
1578: {
1579: e1 = e1->integralPromotions(sc);
1580: e2 = e2->integralPromotions(sc);
1581: }
1582:
1583: Type *t1 = e1->type;
1584: Type *t2 = e2->type;
1585: assert(t1);
1586: Type *t = t1;
1587:
1588: //if (t1) printf("\tt1 = %s\n", t1->toChars());
1589: //if (t2) printf("\tt2 = %s\n", t2->toChars());
1590: #ifdef DEBUG
1591: if (!t2) printf("\te2 = '%s'\n", e2->toChars());
1592: #endif
1593: assert(t2);
1594:
1595: Type *t1b = t1->toBasetype();
1596: Type *t2b = t2->toBasetype();
1597:
1598: TY ty = (TY)Type::impcnvResult[t1b->ty][t2b->ty];
1599: if (ty != Terror)
1600: {
1601: TY ty1 = (TY)Type::impcnvType1[t1b->ty][t2b->ty];
1602: TY ty2 = (TY)Type::impcnvType2[t1b->ty][t2b->ty];
1603:
1604: if (t1b->ty == ty1) // if no promotions
1605: {
1606: if (t1 == t2)
1607: {
1608: t = t1;
1609: goto Lret;
1610: }
1611:
1612: if (t1b == t2b)
1613: {
1614: t = t1b;
1615: goto Lret;
1616: }
1617: }
1618:
1619: t = Type::basic[ty];
1620:
1621: t1 = Type::basic[ty1];
1622: t2 = Type::basic[ty2];
1623: e1 = e1->castTo(sc, t1);
1624: e2 = e2->castTo(sc, t2);
1625: //printf("after typeCombine():\n");
1626: //dump(0);
1627: //printf("ty = %d, ty1 = %d, ty2 = %d\n", ty, ty1, ty2);
1628: goto Lret;
1629: }
1630:
1631: t1 = t1b;
1632: t2 = t2b;
1633:
1634: Lagain:
1635: if (t1 == t2)
1636: {
1637: }
1638: else if (t1->ty == Tpointer && t2->ty == Tpointer)
1639: {
1640: // Bring pointers to compatible type
1641: Type *t1n = t1->nextOf();
1642: Type *t2n = t2->nextOf();
1643:
1644: if (t1n == t2n)
1645: ;
1646: else if (t1n->ty == Tvoid) // pointers to void are always compatible
1647: t = t2;
1648: else if (t2n->ty == Tvoid)
1649: ;
1650: else if (t1n->mod != t2n->mod)
1651: {
1652: t1 = t1n->mutableOf()->constOf()->pointerTo();
1653: t2 = t2n->mutableOf()->constOf()->pointerTo();
1654: t = t1;
1655: goto Lagain;
1656: }
1657: else if (t1n->ty == Tclass && t2n->ty == Tclass)
1658: { ClassDeclaration *cd1 = t1n->isClassHandle();
1659: ClassDeclaration *cd2 = t2n->isClassHandle();
1660: int offset;
1661:
1662: if (cd1->isBaseOf(cd2, &offset))
1663: {
1664: if (offset)
1665: e2 = e2->castTo(sc, t);
1666: }
1667: else if (cd2->isBaseOf(cd1, &offset))
1668: {
1669: t = t2;
1670: if (offset)
1671: e1 = e1->castTo(sc, t);
1672: }
1673: else
1674: goto Lincompatible;
1675: }
1676: else
1677: goto Lincompatible;
1678: }
1679: else if ((t1->ty == Tsarray || t1->ty == Tarray) &&
1680: (e2->op == TOKnull && t2->ty == Tpointer && t2->nextOf()->ty == Tvoid ||
1681: // if e2 is void[]
1682: e2->op == TOKarrayliteral && t2->ty == Tsarray && t2->nextOf()->ty == Tvoid && ((TypeSArray *)t2)->dim->toInteger() == 0 ||
1683: isVoidArrayLiteral(e2, t1))
1684: )
1685: { /* (T[n] op void*) => T[]
1686: * (T[] op void*) => T[]
1687: * (T[n] op void[0]) => T[]
1688: * (T[] op void[0]) => T[]
1689: * (T[n] op void[]) => T[]
1690: * (T[] op void[]) => T[]
1691: */
1692: goto Lx1;
1693: }
1694: else if ((t2->ty == Tsarray || t2->ty == Tarray) &&
1695: (e1->op == TOKnull && t1->ty == Tpointer && t1->nextOf()->ty == Tvoid ||
1696: e1->op == TOKarrayliteral && t1->ty == Tsarray && t1->nextOf()->ty == Tvoid && ((TypeSArray *)t1)->dim->toInteger() == 0 ||
1697: isVoidArrayLiteral(e1, t2))
1698: )
1699: { /* (void* op T[n]) => T[]
1700: * (void* op T[]) => T[]
1701: * (void[0] op T[n]) => T[]
1702: * (void[0] op T[]) => T[]
1703: * (void[] op T[n]) => T[]
1704: * (void[] op T[]) => T[]
1705: */
1706: goto Lx2;
1707: }
1708: else if ((t1->ty == Tsarray || t1->ty == Tarray) && t1->implicitConvTo(t2))
1709: {
1710: goto Lt2;
1711: }
1712: else if ((t2->ty == Tsarray || t2->ty == Tarray) && t2->implicitConvTo(t1))
1713: {
1714: goto Lt1;
1715: }
1716: /* If one is mutable and the other invariant, then retry
1717: * with both of them as const
1718: */
1719: else if ((t1->ty == Tsarray || t1->ty == Tarray || t1->ty == Tpointer) &&
1720: (t2->ty == Tsarray || t2->ty == Tarray || t2->ty == Tpointer) &&
1721: t1->nextOf()->mod != t2->nextOf()->mod
1722: )
1723: { unsigned char mod = MODmerge(t1->nextOf()->mod, t2->nextOf()->mod);
1724:
1725: if (t1->ty == Tpointer)
1726: t1 = t1->nextOf()->castMod(mod)->pointerTo();
1727: else
1728: t1 = t1->nextOf()->castMod(mod)->arrayOf();
1729:
1730: if (t2->ty == Tpointer)
1731: t2 = t2->nextOf()->castMod(mod)->pointerTo();
1732: else
1733: t2 = t2->nextOf()->castMod(mod)->arrayOf();
1734: t = t1;
1735: goto Lagain;
1736: }
1737: else if (t1->ty == Tclass || t2->ty == Tclass)
1738: {
1739: if (t1->mod != t2->mod)
1740: { unsigned char mod = MODmerge(t1->mod, t2->mod);
1741: t1 = t1->castMod(mod);
1742: t2 = t2->castMod(mod);
1743: t = t1;
1744: goto Lagain;
1745: }
1746:
1747: while (1)
1748: {
1749: int i1 = e2->implicitConvTo(t1);
1750: int i2 = e1->implicitConvTo(t2);
1751:
1752: if (i1 && i2)
1753: {
1754: // We have the case of class vs. void*, so pick class
1755: if (t1->ty == Tpointer)
1756: i1 = 0;
1757: else if (t2->ty == Tpointer)
1758: i2 = 0;
1759: }
1760:
1761: if (i2)
1762: {
1763: goto Lt2;
1764: }
1765: else if (i1)
1766: {
1767: goto Lt1;
1768: }
1769: else if (t1->ty == Tclass && t2->ty == Tclass)
1770: { TypeClass *tc1 = (TypeClass *)t1;
1771: TypeClass *tc2 = (TypeClass *)t2;
1772:
1773: /* Pick 'tightest' type
1774: */
1775: ClassDeclaration *cd1 = tc1->sym->baseClass;
1776: ClassDeclaration *cd2 = tc2->sym->baseClass;
1777:
1778: if (cd1 && cd2)
1779: { t1 = cd1->type;
1780: t2 = cd2->type;
1781: }
1782: else if (cd1)
1783: t1 = cd1->type;
1784: else if (cd2)
1785: t2 = cd2->type;
1786: else
1787: goto Lincompatible;
1788: }
1789: else
1790: goto Lincompatible;
1791: }
1792: }
1793: else if (t1->ty == Tstruct && t2->ty == Tstruct)
1794: {
1795: if (((TypeStruct *)t1)->sym != ((TypeStruct *)t2)->sym)
1796: goto Lincompatible;
1797: }
1798: else if ((e1->op == TOKstring || e1->op == TOKnull) && e1->implicitConvTo(t2))
1799: {
1800: goto Lt2;
1801: }
1802: else if ((e2->op == TOKstring || e2->op == TOKnull) && e2->implicitConvTo(t1))
1803: {
1804: goto Lt1;
1805: }
1806: else if (t1->ty == Tsarray && t2->ty == Tsarray &&
1807: e2->implicitConvTo(t1->nextOf()->arrayOf()))
1808: {
1809: Lx1:
1810: t = t1->nextOf()->arrayOf(); // T[]
1811: e1 = e1->castTo(sc, t);
1812: e2 = e2->castTo(sc, t);
1813: }
1814: else if (t1->ty == Tsarray && t2->ty == Tsarray &&
1815: e1->implicitConvTo(t2->nextOf()->arrayOf()))
1816: {
1817: Lx2:
1818: t = t2->nextOf()->arrayOf();
1819: e1 = e1->castTo(sc, t);
1820: e2 = e2->castTo(sc, t);
1821: }
1822: else if (t1->isintegral() && t2->isintegral())
1823: {
1824: assert(t1->ty == t2->ty);
1825: unsigned char mod = MODmerge(t1->mod, t2->mod);
1826:
1827: t1 = t1->castMod(mod);
1828: t2 = t2->castMod(mod);
1829: t = t1;
1830: e1 = e1->castTo(sc, t);
1831: e2 = e2->castTo(sc, t);
1832: goto Lagain;
1833: }
1834: else if (e1->isArrayOperand() && t1->ty == Tarray &&
1835: e2->implicitConvTo(t1->nextOf()))
1836: { // T[] op T
1837: e2 = e2->castTo(sc, t1->nextOf());
1838: t = t1->nextOf()->arrayOf();
1839: }
1840: else if (e2->isArrayOperand() && t2->ty == Tarray &&
1841: e1->implicitConvTo(t2->nextOf()))
1842: { // T op T[]
1843: e1 = e1->castTo(sc, t2->nextOf());
1844: t = t2->nextOf()->arrayOf();
1845:
1846: //printf("test %s\n", e->toChars());
1847: e1 = e1->optimize(WANTvalue);
1848: if (e && e->isCommutative() && e1->isConst())
1849: { /* Swap operands to minimize number of functions generated
1850: */
1851: //printf("swap %s\n", e->toChars());
1852: Expression *tmp = e1;
1853: e1 = e2;
1854: e2 = tmp;
1855: }
1856: }
1857: else
1858: {
1859: Lincompatible:
1860: return 0;
1861: }
1862: Lret:
1863: if (!*pt)
1864: *pt = t;
1865: *pe1 = e1;
1866: *pe2 = e2;
1867: #if 0
1868: printf("-typeMerge() %s op %s\n", e1->toChars(), e2->toChars());
1869: if (e1->type) printf("\tt1 = %s\n", e1->type->toChars());
1870: if (e2->type) printf("\tt2 = %s\n", e2->type->toChars());
1871: printf("\ttype = %s\n", t->toChars());
1872: #endif
1873: //dump(0);
1874: return 1;
1875:
1876:
1877: Lt1:
1878: e2 = e2->castTo(sc, t1);
1879: t = t1;
1880: goto Lret;
1881:
1882: Lt2:
1883: e1 = e1->castTo(sc, t2);
1884: t = t2;
1885: goto Lret;
1886: }
1887:
1888: /************************************
1889: * Bring leaves to common type.
1890: */
1891:
1892: Expression *BinExp::typeCombine(Scope *sc)
1893: {
1894: Type *t1 = e1->type->toBasetype();
1895: Type *t2 = e2->type->toBasetype();
1896:
1897: if (op == TOKmin || op == TOKadd)
1898: {
1899: // struct+struct, where the structs are the same type, and class+class are errors
1900: if (t1->ty == Tstruct)
1901: {
1902: if (t2->ty == Tstruct &&
1903: ((TypeStruct *)t1)->sym == ((TypeStruct *)t2)->sym)
1904: goto Lerror;
1905: }
1906: else if (t1->ty == Tclass)
1907: {
1908: if (t2->ty == Tclass)
1909: goto Lerror;
1910: }
1911: }
1912:
1913: if (!typeMerge(sc, this, &type, &e1, &e2))
1914: goto Lerror;
1915: return this;
1916:
1917: Lerror:
1918: incompatibleTypes();
1919: type = Type::terror;
1920: e1 = new ErrorExp();
1921: e2 = new ErrorExp();
1922: return new ErrorExp();
1923: }
1924:
1925: /***********************************
1926: * Do integral promotions (convertchk).
1927: * Don't convert <array of> to <pointer to>
1928: */
1929:
1930: Expression *Expression::integralPromotions(Scope *sc)
1931: {
1932: Expression *e = this;
1933:
1934: //printf("integralPromotions %s %s\n", e->toChars(), e->type->toChars());
1935: switch (type->toBasetype()->ty)
1936: {
1937: case Tvoid:
1938: error("void has no value");
1939: return new ErrorExp();
1940:
1941: case Tint8:
1942: case Tuns8:
1943: case Tint16:
1944: case Tuns16:
1945: case Tbool:
1946: case Tchar:
1947: case Twchar:
1948: e = e->castTo(sc, Type::tint32);
1949: break;
1950:
1951: case Tdchar:
1952: e = e->castTo(sc, Type::tuns32);
1953: break;
1954: }
1955: return e;
1956: }
1957:
1958: /***********************************
1959: * See if both types are arrays that can be compared
1960: * for equality. Return !=0 if so.
1961: * If they are arrays, but incompatible, issue error.
1962: * This is to enable comparing things like an immutable
1963: * array with a mutable one.
1964: */
1965:
1966: int arrayTypeCompatible(Loc loc, Type *t1, Type *t2)
1967: {
1968: t1 = t1->toBasetype();
1969: t2 = t2->toBasetype();
1970:
1971: if ((t1->ty == Tarray || t1->ty == Tsarray || t1->ty == Tpointer) &&
1972: (t2->ty == Tarray || t2->ty == Tsarray || t2->ty == Tpointer))
1973: {
1974: if (t1->nextOf()->implicitConvTo(t2->nextOf()) < MATCHconst &&
1975: t2->nextOf()->implicitConvTo(t1->nextOf()) < MATCHconst &&
1976: (t1->nextOf()->ty != Tvoid && t2->nextOf()->ty != Tvoid))
1977: {
1978: error(loc, "array equality comparison type mismatch, %s vs %s", t1->toChars(), t2->toChars());
1979: }
1980: return 1;
1981: }
1982: return 0;
1983: }
1984:
1985: /***********************************
1986: * See if both types are arrays that can be compared
1987: * for equality without any casting. Return !=0 if so.
1988: * This is to enable comparing things like an immutable
1989: * array with a mutable one.
1990: */
1991: int arrayTypeCompatibleWithoutCasting(Loc loc, Type *t1, Type *t2)
1992: {
1993: t1 = t1->toBasetype();
1994: t2 = t2->toBasetype();
1995:
1996: if ((t1->ty == Tarray || t1->ty == Tsarray || t1->ty == Tpointer) &&
1997: t2->ty == t1->ty)
1998: {
1999: if (t1->nextOf()->implicitConvTo(t2->nextOf()) >= MATCHconst ||
2000: t2->nextOf()->implicitConvTo(t1->nextOf()) >= MATCHconst)
2001: return 1;
2002: }
2003: return 0;
2004: }
2005:
2006:
2007: /******************************************************************/
2008:
2009: /* Determine the integral ranges of an expression.
2010: * This is used to determine if implicit narrowing conversions will
2011: * be allowed.
2012: */
2013:
2014: uinteger_t getMask(uinteger_t v)
2015: {
2016: // Ref: http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
2017: v |= v >> 1;
2018: v |= v >> 2;
2019: v |= v >> 4;
2020: v |= v >> 8;
2021: v |= v >> 16;
2022: v |= v >> 32;
2023: return v /* | 0xff*/;
2024: }
2025: IntRange Expression::getIntRange()
2026: {
2027: return IntRange::fromType(type) DUMP;
2028: }
2029:
2030: IntRange IntegerExp::getIntRange()
2031: {
2032: return IntRange(value).cast(type) DUMP;
2033: }
2034:
2035: IntRange CastExp::getIntRange()
2036: {
2037: return e1->getIntRange().cast(type) DUMP;
2038: }
2039:
2040: IntRange AddExp::getIntRange()
2041: {
2042: IntRange ir1 = e1->getIntRange();
2043: IntRange ir2 = e2->getIntRange();
2044: return IntRange(ir1.imin + ir2.imin, ir1.imax + ir2.imax).cast(type) DUMP;
2045: }
2046:
2047: IntRange MinExp::getIntRange()
2048: {
2049: IntRange ir1 = e1->getIntRange();
2050: IntRange ir2 = e2->getIntRange();
2051: return IntRange(ir1.imin - ir2.imax, ir1.imax - ir2.imin).cast(type) DUMP;
2052: }
2053:
2054: IntRange DivExp::getIntRange()
2055: {
2056: IntRange ir1 = e1->getIntRange();
2057: IntRange ir2 = e2->getIntRange();
2058:
2059: // Should we ignore the possibility of div-by-0???
2060: if (ir2.containsZero())
2061: return Expression::getIntRange() DUMP;
2062:
2063: // [a,b] / [c,d] = [min (a/c, a/d, b/c, b/d), max (a/c, a/d, b/c, b/d)]
2064: SignExtendedNumber bdy[4] = {
2065: ir1.imin / ir2.imin,
2066: ir1.imin / ir2.imax,
2067: ir1.imax / ir2.imin,
2068: ir1.imax / ir2.imax
2069: };
2070: return IntRange::fromNumbers4(bdy).cast(type) DUMP;
2071: }
2072:
2073: IntRange MulExp::getIntRange()
2074: {
2075: IntRange ir1 = e1->getIntRange();
2076: IntRange ir2 = e2->getIntRange();
2077:
2078: // [a,b] * [c,d] = [min (ac, ad, bc, bd), max (ac, ad, bc, bd)]
2079: SignExtendedNumber bdy[4] = {
2080: ir1.imin * ir2.imin,
2081: ir1.imin * ir2.imax,
2082: ir1.imax * ir2.imin,
2083: ir1.imax * ir2.imax
2084: };
2085: return IntRange::fromNumbers4(bdy).cast(type) DUMP;
2086: }
2087:
2088: IntRange ModExp::getIntRange()
2089: {
2090: IntRange irNum = e1->getIntRange();
2091: IntRange irDen = e2->getIntRange().absNeg();
2092:
2093: /*
2094: due to the rules of D (C)'s % operator, we need to consider the cases
2095: separately in different range of signs.
2096:
2097: case 1. [500, 1700] % [7, 23] (numerator is always positive)
2098: = [0, 22]
2099: case 2. [-500, 1700] % [7, 23] (numerator can be negative)
2100: = [-22, 22]
2101: case 3. [-1700, -500] % [7, 23] (numerator is always negative)
2102: = [-22, 0]
2103:
2104: the number 22 is the maximum absolute value in the denomator's range. We
2105: don't care about divide by zero.
2106: */
2107:
2108: // Modding on 0 is invalid anyway.
2109: if (!irDen.imin.negative)
2110: return Expression::getIntRange() DUMP;
2111:
2112: ++ irDen.imin;
2113: irDen.imax = -irDen.imin;
2114:
2115: if (!irNum.imin.negative)
2116: irNum.imin.value = 0;
2117: else if (irNum.imin < irDen.imin)
2118: irNum.imin = irDen.imin;
2119:
2120: if (irNum.imax.negative)
2121: {
2122: irNum.imax.negative = false;
2123: irNum.imax.value = 0;
2124: }
2125: else if (irNum.imax > irDen.imax)
2126: irNum.imax = irDen.imax;
2127:
2128: return irNum.cast(type) DUMP;
2129: }
2130:
2131: // The algorithms for &, |, ^ are not yet the best! Sometimes they will produce
2132: // not the tightest bound. See
2133: // https://github.com/D-Programming-Language/dmd/pull/116
2134: // for detail.
2135: static IntRange unsignedBitwiseAnd(const IntRange& a, const IntRange& b)
2136: {
2137: // the DiffMasks stores the mask of bits which are variable in the range.
2138: uinteger_t aDiffMask = getMask(a.imin.value ^ a.imax.value);
2139: uinteger_t bDiffMask = getMask(b.imin.value ^ b.imax.value);
2140: // Since '&' computes the digitwise-minimum, the we could set all varying
2141: // digits to 0 to get a lower bound, and set all varying digits to 1 to get
2142: // an upper bound.
2143: IntRange result;
2144: result.imin.value = (a.imin.value & ~aDiffMask) & (b.imin.value & ~bDiffMask);
2145: result.imax.value = (a.imax.value | aDiffMask) & (b.imax.value | bDiffMask);
2146: // Sometimes the upper bound is overestimated. The upper bound will never
2147: // exceed the input.
2148: if (result.imax.value > a.imax.value)
2149: result.imax.value = a.imax.value;
2150: if (result.imax.value > b.imax.value)
2151: result.imax.value = b.imax.value;
2152: result.imin.negative = result.imax.negative = a.imin.negative && b.imin.negative;
2153: return result;
2154: }
2155: static IntRange unsignedBitwiseOr(const IntRange& a, const IntRange& b)
2156: {
2157: // the DiffMasks stores the mask of bits which are variable in the range.
2158: uinteger_t aDiffMask = getMask(a.imin.value ^ a.imax.value);
2159: uinteger_t bDiffMask = getMask(b.imin.value ^ b.imax.value);
2160: // The imax algorithm by Adam D. Ruppe.
2161: // http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=108796
2162: IntRange result;
2163: result.imin.value = (a.imin.value & ~aDiffMask) | (b.imin.value & ~bDiffMask);
2164: result.imax.value = a.imax.value | b.imax.value | getMask(a.imax.value & b.imax.value);
2165: // Sometimes the lower bound is underestimated. The lower bound will never
2166: // less than the input.
2167: if (result.imin.value < a.imin.value)
2168: result.imin.value = a.imin.value;
2169: if (result.imin.value < b.imin.value)
2170: result.imin.value = b.imin.value;
2171: result.imin.negative = result.imax.negative = a.imin.negative || b.imin.negative;
2172: return result;
2173: }
2174: static IntRange unsignedBitwiseXor(const IntRange& a, const IntRange& b)
2175: {
2176: // the DiffMasks stores the mask of bits which are variable in the range.
2177: uinteger_t aDiffMask = getMask(a.imin.value ^ a.imax.value);
2178: uinteger_t bDiffMask = getMask(b.imin.value ^ b.imax.value);
2179: IntRange result;
2180: result.imin.value = (a.imin.value ^ b.imin.value) & ~(aDiffMask | bDiffMask);
2181: result.imax.value = (a.imax.value ^ b.imax.value) | (aDiffMask | bDiffMask);
2182: result.imin.negative = result.imax.negative = a.imin.negative != b.imin.negative;
2183: return result;
2184: }
2185:
2186:
2187: IntRange AndExp::getIntRange()
2188: {
2189: IntRange ir1 = e1->getIntRange();
2190: IntRange ir2 = e2->getIntRange();
2191:
2192: IntRange ir1neg, ir1pos, ir2neg, ir2pos;
2193: bool has1neg, has1pos, has2neg, has2pos;
2194:
2195: ir1.splitBySign(ir1neg, has1neg, ir1pos, has1pos);
2196: ir2.splitBySign(ir2neg, has2neg, ir2pos, has2pos);
2197:
2198: IntRange result;
2199: bool hasResult = false;
2200: if (has1pos && has2pos)
2201: result.unionOrAssign(unsignedBitwiseAnd(ir1pos, ir2pos), /*ref*/hasResult);
2202: if (has1pos && has2neg)
2203: result.unionOrAssign(unsignedBitwiseAnd(ir1pos, ir2neg), /*ref*/hasResult);
2204: if (has1neg && has2pos)
2205: result.unionOrAssign(unsignedBitwiseAnd(ir1neg, ir2pos), /*ref*/hasResult);
2206: if (has1neg && has2neg)
2207: result.unionOrAssign(unsignedBitwiseAnd(ir1neg, ir2neg), /*ref*/hasResult);
2208: assert(hasResult);
2209: return result.cast(type) DUMP;
2210: }
2211:
2212: IntRange OrExp::getIntRange()
2213: {
2214: IntRange ir1 = e1->getIntRange();
2215: IntRange ir2 = e2->getIntRange();
2216:
2217: IntRange ir1neg, ir1pos, ir2neg, ir2pos;
2218: bool has1neg, has1pos, has2neg, has2pos;
2219:
2220: ir1.splitBySign(ir1neg, has1neg, ir1pos, has1pos);
2221: ir2.splitBySign(ir2neg, has2neg, ir2pos, has2pos);
2222:
2223: IntRange result;
2224: bool hasResult = false;
2225: if (has1pos && has2pos)
2226: result.unionOrAssign(unsignedBitwiseOr(ir1pos, ir2pos), /*ref*/hasResult);
2227: if (has1pos && has2neg)
2228: result.unionOrAssign(unsignedBitwiseOr(ir1pos, ir2neg), /*ref*/hasResult);
2229: if (has1neg && has2pos)
2230: result.unionOrAssign(unsignedBitwiseOr(ir1neg, ir2pos), /*ref*/hasResult);
2231: if (has1neg && has2neg)
2232: result.unionOrAssign(unsignedBitwiseOr(ir1neg, ir2neg), /*ref*/hasResult);
2233:
2234: assert(hasResult);
2235: return result.cast(type) DUMP;
2236: }
2237:
2238: IntRange XorExp::getIntRange()
2239: {
2240: IntRange ir1 = e1->getIntRange();
2241: IntRange ir2 = e2->getIntRange();
2242:
2243: IntRange ir1neg, ir1pos, ir2neg, ir2pos;
2244: bool has1neg, has1pos, has2neg, has2pos;
2245:
2246: ir1.splitBySign(ir1neg, has1neg, ir1pos, has1pos);
2247: ir2.splitBySign(ir2neg, has2neg, ir2pos, has2pos);
2248:
2249: IntRange result;
2250: bool hasResult = false;
2251: if (has1pos && has2pos)
2252: result.unionOrAssign(unsignedBitwiseXor(ir1pos, ir2pos), /*ref*/hasResult);
2253: if (has1pos && has2neg)
2254: result.unionOrAssign(unsignedBitwiseXor(ir1pos, ir2neg), /*ref*/hasResult);
2255: if (has1neg && has2pos)
2256: result.unionOrAssign(unsignedBitwiseXor(ir1neg, ir2pos), /*ref*/hasResult);
2257: if (has1neg && has2neg)
2258: result.unionOrAssign(unsignedBitwiseXor(ir1neg, ir2neg), /*ref*/hasResult);
2259:
2260: assert(hasResult);
2261: return result.cast(type) DUMP;
2262: }
2263:
2264: IntRange ShlExp::getIntRange()
2265: {
2266: IntRange ir1 = e1->getIntRange();
2267: IntRange ir2 = e2->getIntRange();
2268:
2269: if (ir2.imin.negative)
2270: ir2 = IntRange(SignExtendedNumber(0), SignExtendedNumber(64));
2271:
2272: SignExtendedNumber lower = ir1.imin << (ir1.imin.negative ? ir2.imax : ir2.imin);
2273: SignExtendedNumber upper = ir1.imax << (ir1.imax.negative ? ir2.imin : ir2.imax);
2274:
2275: return IntRange(lower, upper).cast(type) DUMP;
2276: }
2277:
2278: IntRange ShrExp::getIntRange()
2279: {
2280: IntRange ir1 = e1->getIntRange();
2281: IntRange ir2 = e2->getIntRange();
2282:
2283: if (ir2.imin.negative)
2284: ir2 = IntRange(SignExtendedNumber(0), SignExtendedNumber(64));
2285:
2286: SignExtendedNumber lower = ir1.imin >> (ir1.imin.negative ? ir2.imin : ir2.imax);
2287: SignExtendedNumber upper = ir1.imax >> (ir1.imax.negative ? ir2.imax : ir2.imin);
2288:
2289: return IntRange(lower, upper).cast(type) DUMP;
2290: }
2291:
2292: IntRange UshrExp::getIntRange()
2293: {
2294: IntRange ir1 = e1->getIntRange().castUnsigned(e1->type);
2295: IntRange ir2 = e2->getIntRange();
2296:
2297: if (ir2.imin.negative)
2298: ir2 = IntRange(SignExtendedNumber(0), SignExtendedNumber(64));
2299:
2300: return IntRange(ir1.imin >> ir2.imax, ir1.imax >> ir2.imin).cast(type) DUMP;
2301:
2302: }
2303:
2304: IntRange CommaExp::getIntRange()
2305: {
2306: return e2->getIntRange() DUMP;
2307: }
2308:
2309: IntRange ComExp::getIntRange()
2310: {
2311: IntRange ir = e1->getIntRange();
2312: return IntRange(SignExtendedNumber(~ir.imax.value, !ir.imax.negative),
2313: SignExtendedNumber(~ir.imin.value, !ir.imin.negative)).cast(type) DUMP;
2314: }
2315:
2316: IntRange NegExp::getIntRange()
2317: {
2318: IntRange ir = e1->getIntRange();
2319: return IntRange(-ir.imax, -ir.imin).cast(type) DUMP;
2320: }
2321:
2322: