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: