
/* Compiler implementation of the D programming language
 * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
 * written by Walter Bright
 * http://www.digitalmars.com
 * Distributed under the Boost Software License, Version 1.0.
 * http://www.boost.org/LICENSE_1_0.txt
 * https://github.com/D-Programming-Language/dmd/blob/master/src/cast.c
 */

#include "root/dsystem.h"               // mem{set|cpy}()
#include "root/rmem.h"

#include "mars.h"
#include "expression.h"
#include "mtype.h"
#include "utf.h"
#include "declaration.h"
#include "aggregate.h"
#include "template.h"
#include "scope.h"
#include "id.h"
#include "init.h"
#include "tokens.h"

FuncDeclaration *isFuncAddress(Expression *e, bool *hasOverloads = NULL);
bool isCommutative(TOK op);
MOD MODmerge(MOD mod1, MOD mod2);
void toAutoQualChars(const char **result, Type *t1, Type *t2);

/* ==================== implicitCast ====================== */

/**************************************
 * Do an implicit cast.
 * Issue error if it can't be done.
 */


Expression *implicitCastTo(Expression *e, Scope *sc, Type *t)
{
    class ImplicitCastTo : public Visitor
    {
    public:
        Type *t;
        Scope *sc;
        Expression *result;

        ImplicitCastTo(Scope *sc, Type *t)
            : t(t), sc(sc)
        {
            result = NULL;
        }

        void visit(Expression *e)
        {
            //printf("Expression::implicitCastTo(%s of type %s) => %s\n", e->toChars(), e->type->toChars(), t->toChars());

            MATCH match = e->implicitConvTo(t);
            if (match)
            {
                if (match == MATCHconst &&
                    (e->type->constConv(t) ||
                     (!e->isLvalue() && e->type->equivalent(t))))
                {
                    /* Do not emit CastExp for const conversions and
                     * unique conversions on rvalue.
                     */
                    result = e->copy();
                    result->type = t;
                    return;
                }
                result = e->castTo(sc, t);
                return;
            }

            result = e->optimize(WANTvalue);
            if (result != e)
            {
                result->accept(this);
                return;
            }

            if (t->ty != Terror && e->type->ty != Terror)
            {
                if (!t->deco)
                {
                    e->error("forward reference to type %s", t->toChars());
                }
                else
                {
                    //printf("type %p ty %d deco %p\n", type, type->ty, type->deco);
                    //type = type->semantic(loc, sc);
                    //printf("type %s t %s\n", type->deco, t->deco);
                    const char *ts[2];
                    toAutoQualChars(ts, e->type, t);
                    e->error("cannot implicitly convert expression (%s) of type %s to %s",
                        e->toChars(), ts[0], ts[1]);
                }
            }
            result = new ErrorExp();
        }

        void visit(StringExp *e)
        {
            //printf("StringExp::implicitCastTo(%s of type %s) => %s\n", e->toChars(), e->type->toChars(), t->toChars());
            visit((Expression *)e);
            if (result->op == TOKstring)
            {
                // Retain polysemous nature if it started out that way
                ((StringExp *)result)->committed = e->committed;
            }
        }

        void visit(ErrorExp *e)
        {
            result = e;
        }

        void visit(FuncExp *e)
        {
            //printf("FuncExp::implicitCastTo type = %p %s, t = %s\n", e->type, e->type ? e->type->toChars() : NULL, t->toChars());
            FuncExp *fe;
            if (e->matchType(t, sc, &fe) > MATCHnomatch)
            {
                result = fe;
                return;
            }
            visit((Expression *)e);
        }

        void visit(ArrayLiteralExp *e)
        {
            visit((Expression *)e);

            Type *tb = result->type->toBasetype();
            if (tb->ty == Tarray && global.params.useTypeInfo && Type::dtypeinfo)
                semanticTypeInfo(sc, ((TypeDArray *)tb)->next);
        }

        void visit(SliceExp *e)
        {
            visit((Expression *)e);
            if (result->op != TOKslice)
                return;

            e = (SliceExp *)result;
            if (e->e1->op == TOKarrayliteral)
            {
                ArrayLiteralExp *ale = (ArrayLiteralExp *)e->e1;
                Type *tb = t->toBasetype();
                Type *tx;
                if (tb->ty == Tsarray)
                    tx = tb->nextOf()->sarrayOf(ale->elements ? ale->elements->length : 0);
                else
                    tx = tb->nextOf()->arrayOf();
                e->e1 = ale->implicitCastTo(sc, tx);
            }
        }
    };

    ImplicitCastTo v(sc, t);
    e->accept(&v);
    return v.result;
}

/*******************************************
 * Return MATCH level of implicitly converting e to type t.
 * Don't do the actual cast; don't change e.
 */

MATCH implicitConvTo(Expression *e, Type *t)
{
    class ImplicitConvTo : public Visitor
    {
    public:
        Type *t;
        MATCH result;

        ImplicitConvTo(Type *t)
            : t(t)
        {
            result = MATCHnomatch;
        }

        void visit(Expression *e)
        {
            //static int nest; if (++nest == 10) halt();
            if (t == Type::terror)
                return;
            if (!e->type)
            {
                e->error("%s is not an expression", e->toChars());
                e->type = Type::terror;
            }
            Expression *ex = e->optimize(WANTvalue);
            if (ex->type->equals(t))
            {
                result = MATCHexact;
                return;
            }
            if (ex != e)
            {
                //printf("\toptimized to %s of type %s\n", e->toChars(), e->type->toChars());
                result = ex->implicitConvTo(t);
                return;
            }
            MATCH match = e->type->implicitConvTo(t);
            if (match != MATCHnomatch)
            {
                result = match;
                return;
            }

            /* See if we can do integral narrowing conversions
             */
            if (e->type->isintegral() && t->isintegral() &&
                e->type->isTypeBasic() && t->isTypeBasic())
            {
                IntRange src = getIntRange(e);
                IntRange target = IntRange::fromType(t);
                if (target.contains(src))
                {
                    result = MATCHconvert;
                    return;
                }
            }
        }

        /******
         * Given expression e of type t, see if we can implicitly convert e
         * to type tprime, where tprime is type t with mod bits added.
         * Returns:
         *      match level
         */
        static MATCH implicitMod(Expression *e, Type *t, MOD mod)
        {
            Type *tprime;
            if (t->ty == Tpointer)
                tprime = t->nextOf()->castMod(mod)->pointerTo();
            else if (t->ty == Tarray)
                tprime = t->nextOf()->castMod(mod)->arrayOf();
            else if (t->ty == Tsarray)
                tprime = t->nextOf()->castMod(mod)->sarrayOf(t->size() / t->nextOf()->size());
            else
                tprime = t->castMod(mod);

            return e->implicitConvTo(tprime);
        }

        static MATCH implicitConvToAddMin(BinExp *e, Type *t)
        {
            /* Is this (ptr +- offset)? If so, then ask ptr
             * if the conversion can be done.
             * This is to support doing things like implicitly converting a mutable unique
             * pointer to an immutable pointer.
             */

            Type *typeb = e->type->toBasetype();
            Type *tb = t->toBasetype();
            if (typeb->ty != Tpointer || tb->ty != Tpointer)
                return MATCHnomatch;

            Type *t1b = e->e1->type->toBasetype();
            Type *t2b = e->e2->type->toBasetype();
            if (t1b->ty == Tpointer && t2b->isintegral() &&
                t1b->equivalent(tb))
            {
                // ptr + offset
                // ptr - offset
                MATCH m = e->e1->implicitConvTo(t);
                return (m > MATCHconst) ? MATCHconst : m;
            }
            if (t2b->ty == Tpointer && t1b->isintegral() &&
                t2b->equivalent(tb))
            {
                // offset + ptr
                MATCH m = e->e2->implicitConvTo(t);
                return (m > MATCHconst) ? MATCHconst : m;
            }

            return MATCHnomatch;
        }

        void visit(AddExp *e)
        {
            visit((Expression *)e);
            if (result == MATCHnomatch)
                result = implicitConvToAddMin(e, t);
        }

        void visit(MinExp *e)
        {
            visit((Expression *)e);
            if (result == MATCHnomatch)
                result = implicitConvToAddMin(e, t);
        }

        void visit(IntegerExp *e)
        {
            MATCH m = e->type->implicitConvTo(t);
            if (m >= MATCHconst)
            {
                result = m;
                return;
            }

            TY ty = e->type->toBasetype()->ty;
            TY toty = t->toBasetype()->ty;
            TY oldty = ty;

            if (m == MATCHnomatch && t->ty == Tenum)
                return;

            if (t->ty == Tvector)
            {
                TypeVector *tv = (TypeVector *)t;
                TypeBasic *tb = tv->elementType();
                if (tb->ty == Tvoid)
                    return;
                toty = tb->ty;
            }

            switch (ty)
            {
                case Tbool:
                case Tint8:
                case Tchar:
                case Tuns8:
                case Tint16:
                case Tuns16:
                case Twchar:
                    ty = Tint32;
                    break;

                case Tdchar:
                    ty = Tuns32;
                    break;

                default:
                    break;
            }

            // Only allow conversion if no change in value
            dinteger_t value = e->toInteger();
            switch (toty)
            {
                case Tbool:
                    if ((value & 1) != value)
                        return;
                    break;

                case Tint8:
                    if (ty == Tuns64 && value & ~0x7FUL)
                        return;
                    else if ((signed char)value != (sinteger_t)value)
                        return;
                    break;

                case Tchar:
                    if ((oldty == Twchar || oldty == Tdchar) && value > 0x7F)
                        return;
                    /* fall through */
                case Tuns8:
                    //printf("value = %llu %llu\n", (dinteger_t)(unsigned char)value, value);
                    if ((unsigned char)value != value)
                        return;
                    break;

                case Tint16:
                    if (ty == Tuns64 && value & ~0x7FFFUL)
                        return;
                    else if ((short)value != (sinteger_t)value)
                        return;
                    break;

                case Twchar:
                    if (oldty == Tdchar && value > 0xD7FF && value < 0xE000)
                        return;
                    /* fall through */
                case Tuns16:
                    if ((unsigned short)value != value)
                        return;
                    break;

                case Tint32:
                    if (ty == Tuns32)
                    {
                    }
                    else if (ty == Tuns64 && value & ~0x7FFFFFFFUL)
                        return;
                    else if ((int)value != (sinteger_t)value)
                        return;
                    break;

                case Tuns32:
                    if (ty == Tint32)
                    {
                    }
                    else if ((unsigned)value != value)
                        return;
                    break;

                case Tdchar:
                    if (value > 0x10FFFFUL)
                        return;
                    break;

                case Tfloat32:
                {
                    volatile float f;
                    if (e->type->isunsigned())
                    {
                        f = (float)value;
                        if (f != value)
                            return;
                    }
                    else
                    {
                        f = (float)(sinteger_t)value;
                        if (f != (sinteger_t)value)
                            return;
                    }
                    break;
                }

                case Tfloat64:
                {
                    volatile double f;
                    if (e->type->isunsigned())
                    {
                        f = (double)value;
                        if (f != value)
                            return;
                    }
                    else
                    {
                        f = (double)(sinteger_t)value;
                        if (f != (sinteger_t)value)
                            return;
                    }
                    break;
                }

                case Tfloat80:
                {
                    volatile_longdouble f;
                    if (e->type->isunsigned())
                    {
                        f = ldouble(value);
                        if ((dinteger_t)f != value) // isn't this a noop, because the compiler prefers ld
                            return;
                    }
                    else
                    {
                        f = ldouble((sinteger_t)value);
                        if ((sinteger_t)f != (sinteger_t)value)
                            return;
                    }
                    break;
                }

                case Tpointer:
                    //printf("type = %s\n", type->toBasetype()->toChars());
                    //printf("t = %s\n", t->toBasetype()->toChars());
                    if (ty == Tpointer &&
                        e->type->toBasetype()->nextOf()->ty == t->toBasetype()->nextOf()->ty)
                    {
                        /* Allow things like:
                         *      const char* P = cast(char *)3;
                         *      char* q = P;
                         */
                        break;
                    }
                    /* fall through */

                default:
                    visit((Expression *)e);
                return;
            }

            //printf("MATCHconvert\n");
            result = MATCHconvert;
        }

        void visit(ErrorExp *)
        {
            // no match
        }

        void visit(NullExp *e)
        {
            if (e->type->equals(t))
            {
                result = MATCHexact;
                return;
            }

            /* Allow implicit conversions from immutable to mutable|const,
             * and mutable to immutable. It works because, after all, a null
             * doesn't actually point to anything.
             */
            if (t->equivalent(e->type))
            {
                result = MATCHconst;
                return;
            }

            visit((Expression *)e);
        }

        void visit(StructLiteralExp *e)
        {
            visit((Expression *)e);
            if (result != MATCHnomatch)
                return;
            if (e->type->ty == t->ty && e->type->ty == Tstruct &&
                ((TypeStruct *)e->type)->sym == ((TypeStruct *)t)->sym)
            {
                result = MATCHconst;
                for (size_t i = 0; i < e->elements->length; i++)
                {
                    Expression *el = (*e->elements)[i];
                    if (!el)
                        continue;
                    Type *te = el->type;
                    te = e->sd->fields[i]->type->addMod(t->mod);
                    MATCH m2 = el->implicitConvTo(te);
                    //printf("\t%s => %s, match = %d\n", el->toChars(), te->toChars(), m2);
                    if (m2 < result)
                        result = m2;
                }
            }
        }

        void visit(StringExp *e)
        {
            if (!e->committed && t->ty == Tpointer && t->nextOf()->ty == Tvoid)
                return;

            if (e->type->ty == Tsarray || e->type->ty == Tarray || e->type->ty == Tpointer)
            {
                TY tyn = e->type->nextOf()->ty;
                if (tyn == Tchar || tyn == Twchar || tyn == Tdchar)
                {
                    switch (t->ty)
                    {
                        case Tsarray:
                            if (e->type->ty == Tsarray)
                            {
                                TY tynto = t->nextOf()->ty;
                                if (tynto == tyn)
                                {
                                    if (((TypeSArray *)e->type)->dim->toInteger() ==
                                        ((TypeSArray *)t)->dim->toInteger())
                                    {
                                        result = MATCHexact;
                                    }
                                    return;
                                }
                                if (tynto == Tchar || tynto == Twchar || tynto == Tdchar)
                                {
                                    if (e->committed && tynto != tyn)
                                        return;
                                    size_t fromlen = e->numberOfCodeUnits(tynto);
                                    size_t tolen = (size_t)((TypeSArray *)t)->dim->toInteger();
                                    if (tolen < fromlen)
                                        return;
                                    if (tolen != fromlen)
                                    {
                                        // implicit length extending
                                        result = MATCHconvert;
                                        return;
                                    }
                                }
                                if (!e->committed && (tynto == Tchar || tynto == Twchar || tynto == Tdchar))
                                {
                                    result = MATCHexact;
                                    return;
                                }
                            }
                            else if (e->type->ty == Tarray)
                            {
                                TY tynto = t->nextOf()->ty;
                                if (tynto == Tchar || tynto == Twchar || tynto == Tdchar)
                                {
                                    if (e->committed && tynto != tyn)
                                        return;
                                    size_t fromlen = e->numberOfCodeUnits(tynto);
                                    size_t tolen = (size_t)((TypeSArray *)t)->dim->toInteger();
                                    if (tolen < fromlen)
                                        return;
                                    if (tolen != fromlen)
                                    {
                                        // implicit length extending
                                        result = MATCHconvert;
                                        return;
                                    }
                                }
                                if (tynto == tyn)
                                {
                                    result = MATCHexact;
                                    return;
                                }
                                if (!e->committed && (tynto == Tchar || tynto == Twchar || tynto == Tdchar))
                                {
                                    result = MATCHexact;
                                    return;
                                }
                            }
                            /* fall through */
                        case Tarray:
                        case Tpointer:
                            Type *tn = t->nextOf();
                            MATCH m = MATCHexact;
                            if (e->type->nextOf()->mod != tn->mod)
                            {
                                if (!tn->isConst())
                                    return;
                                m = MATCHconst;
                            }
                            if (!e->committed)
                            {
                                switch (tn->ty)
                                {
                                    case Tchar:
                                        if (e->postfix == 'w' || e->postfix == 'd')
                                            m = MATCHconvert;
                                        result = m;
                                        return;
                                    case Twchar:
                                        if (e->postfix != 'w')
                                            m = MATCHconvert;
                                        result = m;
                                        return;
                                    case Tdchar:
                                        if (e->postfix != 'd')
                                            m = MATCHconvert;
                                        result = m;
                                        return;
                                }
                            }
                            break;
                    }
                }
            }

            visit((Expression *)e);
        }

        void visit(ArrayLiteralExp *e)
        {
            Type *typeb = e->type->toBasetype();
            Type *tb = t->toBasetype();
            if ((tb->ty == Tarray || tb->ty == Tsarray) &&
                (typeb->ty == Tarray || typeb->ty == Tsarray))
            {
                result = MATCHexact;
                Type *typen = typeb->nextOf()->toBasetype();

                if (tb->ty == Tsarray)
                {
                    TypeSArray *tsa = (TypeSArray *)tb;
                    if (e->elements->length != tsa->dim->toInteger())
                        result = MATCHnomatch;
                }

                Type *telement = tb->nextOf();
                if (!e->elements->length)
                {
                    if (typen->ty != Tvoid)
                        result = typen->implicitConvTo(telement);
                }
                else
                {
                    if (e->basis)
                    {
                        MATCH m = e->basis->implicitConvTo(telement);
                        if (m < result)
                            result = m;
                    }
                    for (size_t i = 0; i < e->elements->length; i++)
                    {
                        Expression *el = (*e->elements)[i];
                        if (result == MATCHnomatch)
                            break;
                        if (!el)
                            continue;
                        MATCH m = el->implicitConvTo(telement);
                        if (m < result)
                            result = m;                     // remember worst match
                    }
                }

                if (!result)
                    result = e->type->implicitConvTo(t);

                return;
            }
            else if (tb->ty == Tvector &&
                (typeb->ty == Tarray || typeb->ty == Tsarray))
            {
                result = MATCHexact;
                // Convert array literal to vector type
                TypeVector *tv = (TypeVector *)tb;
                TypeSArray *tbase = (TypeSArray *)tv->basetype;
                assert(tbase->ty == Tsarray);
                const size_t edim = e->elements->length;
                const size_t tbasedim = tbase->dim->toInteger();
                if (edim > tbasedim)
                {
                    result = MATCHnomatch;
                    return;
                }

                Type *telement = tv->elementType();
                if (edim < tbasedim)
                {
                    Expression *el = typeb->nextOf()->defaultInitLiteral(e->loc);
                    MATCH m = el->implicitConvTo(telement);
                    if (m < result)
                        result = m; // remember worst match
                }
                for (size_t i = 0; i < edim; i++)
                {
                    Expression *el = (*e->elements)[i];
                    MATCH m = el->implicitConvTo(telement);
                    if (m < result)
                        result = m;                     // remember worst match
                    if (result == MATCHnomatch)
                        break;                          // no need to check for worse
                }
                return;
            }

            visit((Expression *)e);
        }

        void visit(AssocArrayLiteralExp *e)
        {
            Type *typeb = e->type->toBasetype();
            Type *tb = t->toBasetype();
            if (tb->ty == Taarray && typeb->ty == Taarray)
            {
                result = MATCHexact;
                for (size_t i = 0; i < e->keys->length; i++)
                {
                    Expression *el = (*e->keys)[i];
                    MATCH m = el->implicitConvTo(((TypeAArray *)tb)->index);
                    if (m < result)
                        result = m;                     // remember worst match
                    if (result == MATCHnomatch)
                        break;                          // no need to check for worse
                    el = (*e->values)[i];
                    m = el->implicitConvTo(tb->nextOf());
                    if (m < result)
                        result = m;                     // remember worst match
                    if (result == MATCHnomatch)
                        break;                          // no need to check for worse
                }
                return;
            }
            else
                visit((Expression *)e);
        }

        void visit(CallExp *e)
        {
            visit((Expression *)e);
            if (result != MATCHnomatch)
                return;

            /* Allow the result of strongly pure functions to
             * convert to immutable
             */
            if (e->f && e->f->isolateReturn())
            {
                result = e->type->immutableOf()->implicitConvTo(t);
                if (result > MATCHconst)    // Match level is MATCHconst at best.
                    result = MATCHconst;
                return;
            }

            /* Conversion is 'const' conversion if:
             * 1. function is pure (weakly pure is ok)
             * 2. implicit conversion only fails because of mod bits
             * 3. each function parameter can be implicitly converted to the mod bits
             */
            Type *tx = e->f ? e->f->type : e->e1->type;
            tx = tx->toBasetype();
            if (tx->ty != Tfunction)
                return;
            TypeFunction *tf = (TypeFunction *)tx;

            if (tf->purity == PUREimpure)
                return;
            if (e->f && e->f->isNested())
                return;

            /* See if fail only because of mod bits.
             *
             * Bugzilla 14155: All pure functions can access global immutable data.
             * So the returned pointer may refer an immutable global data,
             * and then the returned pointer that points non-mutable object
             * cannot be unique pointer.
             *
             * Example:
             *  immutable g;
             *  static this() { g = 1; }
             *  const(int*) foo() pure { return &g; }
             *  void test() {
             *    immutable(int*) ip = foo(); // OK
             *    int* mp = foo();            // should be disallowed
             *  }
             */
            if (e->type->immutableOf()->implicitConvTo(t) < MATCHconst &&
                e->type->addMod(MODshared)->implicitConvTo(t) < MATCHconst &&
                e->type->implicitConvTo(t->addMod(MODshared)) < MATCHconst)
            {
                return;
            }
            // Allow a conversion to immutable type, or
            // conversions of mutable types between thread-local and shared.

            /* Get mod bits of what we're converting to
             */
            Type *tb = t->toBasetype();
            MOD mod = tb->mod;
            if (tf->isref)
                ;
            else
            {
                Type *ti = getIndirection(t);
                if (ti)
                    mod = ti->mod;
            }
            if (mod & MODwild)
                return;                 // not sure what to do with this

            /* Apply mod bits to each function parameter,
             * and see if we can convert the function argument to the modded type
             */

            size_t nparams = tf->parameterList.length();
            size_t j = tf->isDstyleVariadic(); // if TypeInfoArray was prepended
            if (e->e1->op == TOKdotvar)
            {
                /* Treat 'this' as just another function argument
                 */
                DotVarExp *dve = (DotVarExp *)e->e1;
                Type *targ = dve->e1->type;
                if (targ->constConv(targ->castMod(mod)) == MATCHnomatch)
                    return;
            }
            for (size_t i = j; i < e->arguments->length; ++i)
            {
                Expression *earg = (*e->arguments)[i];
                Type *targ = earg->type->toBasetype();
                if (i - j < nparams)
                {
                    Parameter *fparam = tf->parameterList[i - j];
                    if (fparam->storageClass & STClazy)
                        return;                 // not sure what to do with this
                    Type *tparam = fparam->type;
                    if (!tparam)
                        continue;
                    if (fparam->storageClass & (STCout | STCref))
                    {
                        if (targ->constConv(tparam->castMod(mod)) == MATCHnomatch)
                            return;
                        continue;
                    }
                }

                if (implicitMod(earg, targ, mod) == MATCHnomatch)
                    return;
            }

            /* Success
             */
            result = MATCHconst;
        }

        void visit(AddrExp *e)
        {
            result = e->type->implicitConvTo(t);
            //printf("\tresult = %d\n", result);

            if (result != MATCHnomatch)
                return;

            // Look for pointers to functions where the functions are overloaded.

            t = t->toBasetype();

            if (e->e1->op == TOKoverloadset &&
                (t->ty == Tpointer || t->ty == Tdelegate) && t->nextOf()->ty == Tfunction)
            {
                OverExp *eo = (OverExp *)e->e1;
                FuncDeclaration *f = NULL;
                for (size_t i = 0; i < eo->vars->a.length; i++)
                {
                    Dsymbol *s = eo->vars->a[i];
                    FuncDeclaration *f2 = s->isFuncDeclaration();
                    assert(f2);
                    if (f2->overloadExactMatch(t->nextOf()))
                    {
                        if (f)
                        {
                            /* Error if match in more than one overload set,
                             * even if one is a 'better' match than the other.
                             */
                            ScopeDsymbol::multiplyDefined(e->loc, f, f2);
                        }
                        else
                            f = f2;
                        result = MATCHexact;
                    }
                }
            }

            if (e->type->ty == Tpointer && e->type->nextOf()->ty == Tfunction &&
                t->ty == Tpointer && t->nextOf()->ty == Tfunction &&
                e->e1->op == TOKvar)
            {
                /* I don't think this can ever happen -
                 * it should have been
                 * converted to a SymOffExp.
                 */
                assert(0);
            }

            //printf("\tresult = %d\n", result);
        }

        void visit(SymOffExp *e)
        {
            result = e->type->implicitConvTo(t);
            //printf("\tresult = %d\n", result);
            if (result != MATCHnomatch)
                return;

            // Look for pointers to functions where the functions are overloaded.
            t = t->toBasetype();
            if (e->type->ty == Tpointer && e->type->nextOf()->ty == Tfunction &&
                (t->ty == Tpointer || t->ty == Tdelegate) && t->nextOf()->ty == Tfunction)
            {
                if (FuncDeclaration *f = e->var->isFuncDeclaration())
                {
                    f = f->overloadExactMatch(t->nextOf());
                    if (f)
                    {
                        if ((t->ty == Tdelegate && (f->needThis() || f->isNested())) ||
                            (t->ty == Tpointer && !(f->needThis() || f->isNested())))
                        {
                            result = MATCHexact;
                        }
                    }
                }
            }
            //printf("\tresult = %d\n", result);
        }

        void visit(DelegateExp *e)
        {
            result = e->type->implicitConvTo(t);
            if (result != MATCHnomatch)
                return;

            // Look for pointers to functions where the functions are overloaded.
            t = t->toBasetype();
            if (e->type->ty == Tdelegate &&
                t->ty == Tdelegate)
            {
                if (e->func && e->func->overloadExactMatch(t->nextOf()))
                    result = MATCHexact;
            }
        }

        void visit(FuncExp *e)
        {
            //printf("FuncExp::implicitConvTo type = %p %s, t = %s\n", e->type, e->type ? e->type->toChars() : NULL, t->toChars());
            MATCH m = e->matchType(t, NULL, NULL, 1);
            if (m > MATCHnomatch)
            {
                result = m;
                return;
            }
            visit((Expression *)e);
        }

        void visit(AndExp *e)
        {
            visit((Expression *)e);
            if (result != MATCHnomatch)
                return;

            MATCH m1 = e->e1->implicitConvTo(t);
            MATCH m2 = e->e2->implicitConvTo(t);

            // Pick the worst match
            result = (m1 < m2) ? m1 : m2;
        }

        void visit(OrExp *e)
        {
            visit((Expression *)e);
            if (result != MATCHnomatch)
                return;

            MATCH m1 = e->e1->implicitConvTo(t);
            MATCH m2 = e->e2->implicitConvTo(t);

            // Pick the worst match
            result = (m1 < m2) ? m1 : m2;
        }

        void visit(XorExp *e)
        {
            visit((Expression *)e);
            if (result != MATCHnomatch)
                return;

            MATCH m1 = e->e1->implicitConvTo(t);
            MATCH m2 = e->e2->implicitConvTo(t);

            // Pick the worst match
            result = (m1 < m2) ? m1 : m2;
        }

        void visit(CondExp *e)
        {
            MATCH m1 = e->e1->implicitConvTo(t);
            MATCH m2 = e->e2->implicitConvTo(t);
            //printf("CondExp: m1 %d m2 %d\n", m1, m2);

            // Pick the worst match
            result = (m1 < m2) ? m1 : m2;
        }

        void visit(CommaExp *e)
        {
            e->e2->accept(this);
        }

        void visit(CastExp *e)
        {
            result = e->type->implicitConvTo(t);
            if (result != MATCHnomatch)
                return;

            if (t->isintegral() &&
                e->e1->type->isintegral() &&
                e->e1->implicitConvTo(t) != MATCHnomatch)
                result = MATCHconvert;
            else
                visit((Expression *)e);
        }

        void visit(NewExp *e)
        {
            visit((Expression *)e);
            if (result != MATCHnomatch)
                return;

            /* Calling new() is like calling a pure function. We can implicitly convert the
             * return from new() to t using the same algorithm as in CallExp, with the function
             * 'arguments' being:
             *    thisexp
             *    newargs
             *    arguments
             *    .init
             * 'member' and 'allocator' need to be pure.
             */

            /* See if fail only because of mod bits
             */
            if (e->type->immutableOf()->implicitConvTo(t->immutableOf()) == MATCHnomatch)
                return;

            /* Get mod bits of what we're converting to
             */
            Type *tb = t->toBasetype();
            MOD mod = tb->mod;
            if (Type *ti = getIndirection(t))
                mod = ti->mod;
            if (mod & MODwild)
                return;                 // not sure what to do with this

            /* Apply mod bits to each argument,
             * and see if we can convert the argument to the modded type
             */

            if (e->thisexp)
            {
                /* Treat 'this' as just another function argument
                 */
                Type *targ = e->thisexp->type;
                if (targ->constConv(targ->castMod(mod)) == MATCHnomatch)
                    return;
            }

            /* Check call to 'allocator', then 'member'
             */
            FuncDeclaration *fd = e->allocator;
            for (int count = 0; count < 2; ++count, (fd = e->member))
            {
                if (!fd)
                    continue;
                if (fd->errors || fd->type->ty != Tfunction)
                    return;     // error
                TypeFunction *tf = (TypeFunction *)fd->type;
                if (tf->purity == PUREimpure)
                    return;     // impure

                if (fd == e->member)
                {
                    if (e->type->immutableOf()->implicitConvTo(t) < MATCHconst &&
                        e->type->addMod(MODshared)->implicitConvTo(t) < MATCHconst &&
                        e->type->implicitConvTo(t->addMod(MODshared)) < MATCHconst)
                    {
                        return;
                    }
                    // Allow a conversion to immutable type, or
                    // conversions of mutable types between thread-local and shared.
                }

                Expressions *args = (fd == e->allocator) ? e->newargs : e->arguments;

                size_t nparams = tf->parameterList.length();
                size_t j = tf->isDstyleVariadic(); // if TypeInfoArray was prepended
                for (size_t i = j; i < e->arguments->length; ++i)
                {
                    Expression *earg = (*args)[i];
                    Type *targ = earg->type->toBasetype();
                    if (i - j < nparams)
                    {
                        Parameter *fparam = tf->parameterList[i - j];
                        if (fparam->storageClass & STClazy)
                            return;                 // not sure what to do with this
                        Type *tparam = fparam->type;
                        if (!tparam)
                            continue;
                        if (fparam->storageClass & (STCout | STCref))
                        {
                            if (targ->constConv(tparam->castMod(mod)) == MATCHnomatch)
                                return;
                            continue;
                        }
                    }

                    if (implicitMod(earg, targ, mod) == MATCHnomatch)
                        return;
                }
            }

            /* If no 'member', then construction is by simple assignment,
             * and just straight check 'arguments'
             */
            if (!e->member && e->arguments)
            {
                for (size_t i = 0; i < e->arguments->length; ++i)
                {
                    Expression *earg = (*e->arguments)[i];
                    if (!earg)  // Bugzilla 14853: if it's on overlapped field
                        continue;
                    Type *targ = earg->type->toBasetype();
                    if (implicitMod(earg, targ, mod) == MATCHnomatch)
                        return;
                }
            }

            /* Consider the .init expression as an argument
             */
            Type *ntb = e->newtype->toBasetype();
            if (ntb->ty == Tarray)
                ntb = ntb->nextOf()->toBasetype();
            if (ntb->ty == Tstruct)
            {
                // Don't allow nested structs - uplevel reference may not be convertible
                StructDeclaration *sd = ((TypeStruct *)ntb)->sym;
                sd->size(e->loc);              // resolve any forward references
                if (sd->isNested())
                    return;
            }
            if (ntb->isZeroInit(e->loc))
            {
                /* Zeros are implicitly convertible, except for special cases.
                 */
                if (ntb->ty == Tclass)
                {
                    /* With new() must look at the class instance initializer.
                     */
                    ClassDeclaration *cd = ((TypeClass *)ntb)->sym;

                    cd->size(e->loc);          // resolve any forward references

                    if (cd->isNested())
                        return;                 // uplevel reference may not be convertible

                    assert(!cd->isInterfaceDeclaration());

                    struct ClassCheck
                    {
                        static bool convertible(Loc loc, ClassDeclaration *cd, MOD mod)
                        {
                            for (size_t i = 0; i < cd->fields.length; i++)
                            {
                                VarDeclaration *v = cd->fields[i];
                                Initializer *init = v->_init;
                                if (init)
                                {
                                    if (init->isVoidInitializer())
                                        ;
                                    else if (ExpInitializer *ei = init->isExpInitializer())
                                    {
                                        Type *tb = v->type->toBasetype();
                                        if (implicitMod(ei->exp, tb, mod) == MATCHnomatch)
                                            return false;
                                    }
                                    else
                                    {
                                        /* Enhancement: handle StructInitializer and ArrayInitializer
                                         */
                                        return false;
                                    }
                                }
                                else if (!v->type->isZeroInit(loc))
                                    return false;
                            }
                            return cd->baseClass ? convertible(loc, cd->baseClass, mod) : true;
                        }
                    };

                    if (!ClassCheck::convertible(e->loc, cd, mod))
                        return;
                }
            }
            else
            {
                Expression *earg = e->newtype->defaultInitLiteral(e->loc);
                Type *targ = e->newtype->toBasetype();

                if (implicitMod(earg, targ, mod) == MATCHnomatch)
                    return;
            }

            /* Success
             */
            result = MATCHconst;
        }

        void visit(SliceExp *e)
        {
            //printf("SliceExp::implicitConvTo e = %s, type = %s\n", e->toChars(), e->type->toChars());
            visit((Expression *)e);
            if (result != MATCHnomatch)
                return;

            Type *tb = t->toBasetype();
            Type *typeb = e->type->toBasetype();
            if (tb->ty == Tsarray && typeb->ty == Tarray)
            {
                typeb = toStaticArrayType(e);
                if (typeb)
                    result = typeb->implicitConvTo(t);
                return;
            }

            /* If the only reason it won't convert is because of the mod bits,
             * then test for conversion by seeing if e1 can be converted with those
             * same mod bits.
             */
            Type *t1b = e->e1->type->toBasetype();
            if (tb->ty == Tarray && typeb->equivalent(tb))
            {
                Type *tbn = tb->nextOf();
                Type *tx = NULL;

                /* If e->e1 is dynamic array or pointer, the uniqueness of e->e1
                 * is equivalent with the uniqueness of the referred data. And in here
                 * we can have arbitrary typed reference for that.
                 */
                if (t1b->ty == Tarray)
                    tx = tbn->arrayOf();
                if (t1b->ty == Tpointer)
                    tx = tbn->pointerTo();

                /* If e->e1 is static array, at least it should be an rvalue.
                 * If not, e->e1 is a reference, and its uniqueness does not link
                 * to the uniqueness of the referred data.
                 */
                if (t1b->ty == Tsarray && !e->e1->isLvalue())
                    tx = tbn->sarrayOf(t1b->size() / tbn->size());

                if (tx)
                {
                    result = e->e1->implicitConvTo(tx);
                    if (result > MATCHconst)    // Match level is MATCHconst at best.
                        result = MATCHconst;
                }
            }

            // Enhancement 10724
            if (tb->ty == Tpointer && e->e1->op == TOKstring)
                e->e1->accept(this);
        }
    };

    ImplicitConvTo v(t);
    e->accept(&v);
    return v.result;
}

Type *toStaticArrayType(SliceExp *e)
{
    if (e->lwr && e->upr)
    {
        // For the following code to work, e should be optimized beforehand.
        // (eg. $ in lwr and upr should be already resolved, if possible)
        Expression *lwr = e->lwr->optimize(WANTvalue);
        Expression *upr = e->upr->optimize(WANTvalue);
        if (lwr->isConst() && upr->isConst())
        {
            size_t len = (size_t)(upr->toUInteger() - lwr->toUInteger());
            return e->type->toBasetype()->nextOf()->sarrayOf(len);
        }
    }
    else
    {
        Type *t1b = e->e1->type->toBasetype();
        if (t1b->ty == Tsarray)
            return t1b;
    }
    return NULL;
}

/* ==================== castTo ====================== */

/**************************************
 * Do an explicit cast.
 * Assume that the 'this' expression does not have any indirections.
 */

Expression *castTo(Expression *e, Scope *sc, Type *t)
{
    class CastTo : public Visitor
    {
    public:
        Type *t;
        Scope *sc;
        Expression *result;

        CastTo(Scope *sc, Type *t)
            : t(t), sc(sc)
        {
            result = NULL;
        }

        void visit(Expression *e)
        {
            //printf("Expression::castTo(this=%s, t=%s)\n", e->toChars(), t->toChars());
            if (e->type->equals(t))
            {
                result = e;
                return;
            }
            if (e->op == TOKvar)
            {
                VarDeclaration *v = ((VarExp *)e)->var->isVarDeclaration();
                if (v && v->storage_class & STCmanifest)
                {
                    result = e->ctfeInterpret();
                    result = result->castTo(sc, t);
                    return;
                }
            }

            Type *tob = t->toBasetype();
            Type *t1b = e->type->toBasetype();
            if (tob->equals(t1b))
            {
                result = e->copy();  // because of COW for assignment to e->type
                result->type = t;
                return;
            }

            /* Make semantic error against invalid cast between concrete types.
             * Assume that 'e' is never be any placeholder expressions.
             * The result of these checks should be consistent with CastExp::toElem().
             */

            // Fat Value types
            const bool tob_isFV = (tob->ty == Tstruct || tob->ty == Tsarray || tob->ty == Tvector);
            const bool t1b_isFV = (t1b->ty == Tstruct || t1b->ty == Tsarray || t1b->ty == Tvector);

            // Fat Reference types
            const bool tob_isFR = (tob->ty == Tarray || tob->ty == Tdelegate);
            const bool t1b_isFR = (t1b->ty == Tarray || t1b->ty == Tdelegate);

            // Reference types
            const bool tob_isR = (tob_isFR || tob->ty == Tpointer || tob->ty == Taarray || tob->ty == Tclass);
            const bool t1b_isR = (t1b_isFR || t1b->ty == Tpointer || t1b->ty == Taarray || t1b->ty == Tclass);

            // Arithmetic types (== valueable basic types)
            const bool tob_isA = ((tob->isintegral() || tob->isfloating()) && tob->ty != Tvector);
            const bool t1b_isA = ((t1b->isintegral() || t1b->isfloating()) && t1b->ty != Tvector);

            if (AggregateDeclaration *t1ad = isAggregate(t1b))
            {
                AggregateDeclaration *toad = isAggregate(tob);
                if (t1ad != toad && t1ad->aliasthis)
                {
                    if (t1b->ty == Tclass && tob->ty == Tclass)
                    {
                        ClassDeclaration *t1cd = t1b->isClassHandle();
                        ClassDeclaration *tocd = tob->isClassHandle();
                        int offset;
                        if (tocd->isBaseOf(t1cd, &offset))
                             goto Lok;
                    }

                    /* Forward the cast to our alias this member, rewrite to:
                     *   cast(to)e1.aliasthis
                     */
                    result = resolveAliasThis(sc, e);
                    result = result->castTo(sc, t);
                    return;
                }
            }
            else if (tob->ty == Tvector && t1b->ty != Tvector)
            {
                //printf("test1 e = %s, e->type = %s, tob = %s\n", e->toChars(), e->type->toChars(), tob->toChars());
                TypeVector *tv = (TypeVector *)tob;
                result = new CastExp(e->loc, e, tv->elementType());
                result = new VectorExp(e->loc, result, tob);
                result = expressionSemantic(result, sc);
                return;
            }
            else if (tob->ty != Tvector && t1b->ty == Tvector)
            {
                // T[n] <-- __vector(U[m])
                if (tob->ty == Tsarray)
                {
                    if (t1b->size(e->loc) == tob->size(e->loc))
                        goto Lok;
                }
                goto Lfail;
            }
            else if (t1b->implicitConvTo(tob) == MATCHconst && t->equals(e->type->constOf()))
            {
                result = e->copy();
                result->type = t;
                return;
            }

            // arithmetic values vs. other arithmetic values
            // arithmetic values vs. T*
            if ((tob_isA && (t1b_isA || t1b->ty == Tpointer)) ||
                (t1b_isA && (tob_isA || tob->ty == Tpointer)))
            {
                goto Lok;
            }

            // arithmetic values vs. references or fat values
            if ((tob_isA && (t1b_isR || t1b_isFV)) ||
                (t1b_isA && (tob_isR || tob_isFV)))
            {
                goto Lfail;
            }

            // Bugzlla 3133: A cast between fat values is possible only when the sizes match.
            if (tob_isFV && t1b_isFV)
            {
                if (t1b->size(e->loc) == tob->size(e->loc))
                    goto Lok;
                e->error("cannot cast expression %s of type %s to %s because of different sizes",
                    e->toChars(), e->type->toChars(), t->toChars());
                result = new ErrorExp();
                return;
            }

            // Fat values vs. null or references
            if ((tob_isFV && (t1b->ty == Tnull || t1b_isR)) ||
                (t1b_isFV && (tob->ty == Tnull || tob_isR)))
            {
                if (tob->ty == Tpointer && t1b->ty == Tsarray)
                {
                    // T[n] sa;
                    // cast(U*)sa; // ==> cast(U*)sa.ptr;
                    result = new AddrExp(e->loc, e, t);
                    return;
                }
                if (tob->ty == Tarray && t1b->ty == Tsarray)
                {
                    // T[n] sa;
                    // cast(U[])sa; // ==> cast(U[])sa[];
                    d_uns64 fsize = t1b->nextOf()->size();
                    d_uns64 tsize = tob->nextOf()->size();
                    if (fsize != tsize)
                    {
                        dinteger_t dim = ((TypeSArray *)t1b)->dim->toInteger();
                        if (tsize == 0 || (dim * fsize) % tsize != 0)
                        {
                            e->error("cannot cast expression `%s` of type `%s` to `%s` since sizes don't line up",
                                     e->toChars(), e->type->toChars(), t->toChars());
                            result = new ErrorExp();
                            return;
                        }
                    }
                    goto Lok;
                }
                goto Lfail;
            }

            /* For references, any reinterpret casts are allowed to same 'ty' type.
             *      T* to U*
             *      R1 function(P1) to R2 function(P2)
             *      R1 delegate(P1) to R2 delegate(P2)
             *      T[] to U[]
             *      V1[K1] to V2[K2]
             *      class/interface A to B  (will be a dynamic cast if possible)
             */
            if (tob->ty == t1b->ty && tob_isR && t1b_isR)
                goto Lok;

            // typeof(null) <-- non-null references or values
            if (tob->ty == Tnull && t1b->ty != Tnull)
                goto Lfail;     // Bugzilla 14629
            // typeof(null) --> non-null references or arithmetic values
            if (t1b->ty == Tnull && tob->ty != Tnull)
                goto Lok;

            // Check size mismatch of references.
            // Tarray and Tdelegate are (void*).sizeof*2, but others have (void*).sizeof.
            if ((tob_isFR && t1b_isR) || (t1b_isFR && tob_isR))
            {
                if (tob->ty == Tpointer && t1b->ty == Tarray)
                {
                    // T[] da;
                    // cast(U*)da; // ==> cast(U*)da.ptr;
                    goto Lok;
                }
                if (tob->ty == Tpointer && t1b->ty == Tdelegate)
                {
                    // void delegate() dg;
                    // cast(U*)dg; // ==> cast(U*)dg.ptr;
                    // Note that it happens even when U is a Tfunction!
                    e->deprecation("casting from %s to %s is deprecated", e->type->toChars(), t->toChars());
                    goto Lok;
                }
                goto Lfail;
            }

            if (t1b->ty == Tvoid && tob->ty != Tvoid)
            {
            Lfail:
                e->error("cannot cast expression %s of type %s to %s",
                    e->toChars(), e->type->toChars(), t->toChars());
                result = new ErrorExp();
                return;
            }

        Lok:
            result = new CastExp(e->loc, e, t);
            result->type = t;       // Don't call semantic()
            //printf("Returning: %s\n", result->toChars());
        }

        void visit(ErrorExp *e)
        {
            result = e;
        }

        void visit(RealExp *e)
        {
            if (!e->type->equals(t))
            {
                if ((e->type->isreal() && t->isreal()) ||
                    (e->type->isimaginary() && t->isimaginary())
                   )
                {
                    result = e->copy();
                    result->type = t;
                }
                else
                    visit((Expression *)e);
                return;
            }
            result = e;
        }

        void visit(ComplexExp *e)
        {
            if (!e->type->equals(t))
            {
                if (e->type->iscomplex() && t->iscomplex())
                {
                    result = e->copy();
                    result->type = t;
                }
                else
                    visit((Expression *)e);
                return;
            }
            result = e;
        }

        void visit(NullExp *e)
        {
            //printf("NullExp::castTo(t = %s) %s\n", t->toChars(), toChars());
            visit((Expression *)e);
            if (result->op == TOKnull)
            {
                NullExp *ex = (NullExp *)result;
                ex->committed = 1;
                return;
            }
        }

        void visit(StructLiteralExp *e)
        {
            visit((Expression *)e);
            if (result->op == TOKstructliteral)
                ((StructLiteralExp *)result)->stype = t; // commit type
        }

        void visit(StringExp *e)
        {
            /* This follows copy-on-write; any changes to 'this'
             * will result in a copy.
             * The this->string member is considered immutable.
             */
            int copied = 0;

            //printf("StringExp::castTo(t = %s), '%s' committed = %d\n", t->toChars(), e->toChars(), e->committed);

            if (!e->committed && t->ty == Tpointer && t->nextOf()->ty == Tvoid)
            {
                e->error("cannot convert string literal to void*");
                result = new ErrorExp();
                return;
            }

            StringExp *se = e;
            if (!e->committed)
            {
                se = (StringExp *)e->copy();
                se->committed = 1;
                copied = 1;
            }

            if (e->type->equals(t))
            {
                result = se;
                return;
            }

            Type *tb = t->toBasetype();
            //printf("\ttype = %s\n", e->type->toChars());
            if (tb->ty == Tdelegate && e->type->toBasetype()->ty != Tdelegate)
            {
                visit((Expression *)e);
                return;
            }

            Type *typeb = e->type->toBasetype();
            if (typeb->equals(tb))
            {
                if (!copied)
                {
                    se = (StringExp *)e->copy();
                    copied = 1;
                }
                se->type = t;
                result = se;
                return;
            }

            /* Handle reinterpret casts:
             *  cast(wchar[3])"abcd"c --> [\u6261, \u6463, \u0000]
             *  cast(wchar[2])"abcd"c --> [\u6261, \u6463]
             *  cast(wchar[1])"abcd"c --> [\u6261]
             */
            if (e->committed && tb->ty == Tsarray && typeb->ty == Tarray)
            {
                se = (StringExp *)e->copy();
                d_uns64 szx = tb->nextOf()->size();
                assert(szx <= 255);
                se->sz = (unsigned char)szx;
                se->len = (size_t)((TypeSArray *)tb)->dim->toInteger();
                se->committed = 1;
                se->type = t;

                /* Assure space for terminating 0
                 */
                if ((se->len + 1) * se->sz > (e->len + 1) * e->sz)
                {
                    void *s = (void *)mem.xmalloc((se->len + 1) * se->sz);
                    memcpy(s, se->string, se->len * se->sz);
                    memset((char *)s + se->len * se->sz, 0, se->sz);
                    se->string = s;
                }
                result = se;
                return;
            }

            if (tb->ty != Tsarray && tb->ty != Tarray && tb->ty != Tpointer)
            {
                if (!copied)
                {
                    se = (StringExp *)e->copy();
                    copied = 1;
                }
                goto Lcast;
            }
            if (typeb->ty != Tsarray && typeb->ty != Tarray && typeb->ty != Tpointer)
            {
                if (!copied)
                {
                    se = (StringExp *)e->copy();
                    copied = 1;
                }
                goto Lcast;
            }

            if (typeb->nextOf()->size() == tb->nextOf()->size())
            {
                if (!copied)
                {
                    se = (StringExp *)e->copy();
                    copied = 1;
                }
                if (tb->ty == Tsarray)
                    goto L2;    // handle possible change in static array dimension
                se->type = t;
                result = se;
                return;
            }

            if (e->committed)
                goto Lcast;

        #define X(tf,tt)        ((int)(tf) * 256 + (int)(tt))
            {
            OutBuffer buffer;
            size_t newlen = 0;
            int tfty = typeb->nextOf()->toBasetype()->ty;
            int ttty = tb->nextOf()->toBasetype()->ty;
            switch (X(tfty, ttty))
            {
                case X(Tchar, Tchar):
                case X(Twchar,Twchar):
                case X(Tdchar,Tdchar):
                    break;

                case X(Tchar, Twchar):
                    for (size_t u = 0; u < e->len;)
                    {
                        unsigned c;
                        const char *p = utf_decodeChar((utf8_t *)se->string, e->len, &u, &c);
                        if (p)
                            e->error("%s", p);
                        else
                            buffer.writeUTF16(c);
                    }
                    newlen = buffer.length() / 2;
                    buffer.writeUTF16(0);
                    goto L1;

                case X(Tchar, Tdchar):
                    for (size_t u = 0; u < e->len;)
                    {
                        unsigned c;
                        const char *p = utf_decodeChar((utf8_t *)se->string, e->len, &u, &c);
                        if (p)
                            e->error("%s", p);
                        buffer.write4(c);
                        newlen++;
                    }
                    buffer.write4(0);
                    goto L1;

                case X(Twchar,Tchar):
                    for (size_t u = 0; u < e->len;)
                    {
                        unsigned c;
                        const char *p = utf_decodeWchar((unsigned short *)se->string, e->len, &u, &c);
                        if (p)
                            e->error("%s", p);
                        else
                            buffer.writeUTF8(c);
                    }
                    newlen = buffer.length();
                    buffer.writeUTF8(0);
                    goto L1;

                case X(Twchar,Tdchar):
                    for (size_t u = 0; u < e->len;)
                    {
                        unsigned c;
                        const char *p = utf_decodeWchar((unsigned short *)se->string, e->len, &u, &c);
                        if (p)
                            e->error("%s", p);
                        buffer.write4(c);
                        newlen++;
                    }
                    buffer.write4(0);
                    goto L1;

                case X(Tdchar,Tchar):
                    for (size_t u = 0; u < e->len; u++)
                    {
                        unsigned c = ((unsigned *)se->string)[u];
                        if (!utf_isValidDchar(c))
                            e->error("invalid UCS-32 char \\U%08x", c);
                        else
                            buffer.writeUTF8(c);
                        newlen++;
                    }
                    newlen = buffer.length();
                    buffer.writeUTF8(0);
                    goto L1;

                case X(Tdchar,Twchar):
                    for (size_t u = 0; u < e->len; u++)
                    {
                        unsigned c = ((unsigned *)se->string)[u];
                        if (!utf_isValidDchar(c))
                            e->error("invalid UCS-32 char \\U%08x", c);
                        else
                            buffer.writeUTF16(c);
                        newlen++;
                    }
                    newlen = buffer.length() / 2;
                    buffer.writeUTF16(0);
                    goto L1;

                L1:
                    if (!copied)
                    {
                        se = (StringExp *)e->copy();
                        copied = 1;
                    }
                    se->string = buffer.extractData();
                    se->len = newlen;

                    {
                        d_uns64 szx = tb->nextOf()->size();
                        assert(szx <= 255);
                        se->sz = (unsigned char)szx;
                    }
                    break;

                default:
                    assert(typeb->nextOf()->size() != tb->nextOf()->size());
                    goto Lcast;
            }
            }
        #undef X
        L2:
            assert(copied);

            // See if need to truncate or extend the literal
            if (tb->ty == Tsarray)
            {
                size_t dim2 = (size_t)((TypeSArray *)tb)->dim->toInteger();

                //printf("dim from = %d, to = %d\n", (int)se->len, (int)dim2);

                // Changing dimensions
                if (dim2 != se->len)
                {
                    // Copy when changing the string literal
                    size_t newsz = se->sz;
                    size_t d = (dim2 < se->len) ? dim2 : se->len;
                    void *s = (void *)mem.xmalloc((dim2 + 1) * newsz);
                    memcpy(s, se->string, d * newsz);
                    // Extend with 0, add terminating 0
                    memset((char *)s + d * newsz, 0, (dim2 + 1 - d) * newsz);
                    se->string = s;
                    se->len = dim2;
                }
            }
            se->type = t;
            result = se;
            return;

        Lcast:
            result = new CastExp(e->loc, se, t);
            result->type = t;        // so semantic() won't be run on e
        }

        void visit(AddrExp *e)
        {
            Type *tb;

            result = e;

            tb = t->toBasetype();
            e->type = e->type->toBasetype();
            if (!tb->equals(e->type))
            {
                // Look for pointers to functions where the functions are overloaded.

                if (e->e1->op == TOKoverloadset &&
                    (t->ty == Tpointer || t->ty == Tdelegate) && t->nextOf()->ty == Tfunction)
                {
                    OverExp *eo = (OverExp *)e->e1;
                    FuncDeclaration *f = NULL;
                    for (size_t i = 0; i < eo->vars->a.length; i++)
                    {
                        Dsymbol *s = eo->vars->a[i];
                        FuncDeclaration *f2 = s->isFuncDeclaration();
                        assert(f2);
                        if (f2->overloadExactMatch(t->nextOf()))
                        {
                            if (f)
                            {
                                /* Error if match in more than one overload set,
                                 * even if one is a 'better' match than the other.
                                 */
                                ScopeDsymbol::multiplyDefined(e->loc, f, f2);
                            }
                            else
                                f = f2;
                        }
                    }
                    if (f)
                    {
                        f->tookAddressOf++;
                        SymOffExp *se = new SymOffExp(e->loc, f, 0, false);
                        expressionSemantic(se, sc);
                        // Let SymOffExp::castTo() do the heavy lifting
                        visit(se);
                        return;
                    }
                }

                if (e->type->ty == Tpointer && e->type->nextOf()->ty == Tfunction &&
                    tb->ty == Tpointer && tb->nextOf()->ty == Tfunction &&
                    e->e1->op == TOKvar)
                {
                    VarExp *ve = (VarExp *)e->e1;
                    FuncDeclaration *f = ve->var->isFuncDeclaration();
                    if (f)
                    {
                        assert(f->isImportedSymbol());
                        f = f->overloadExactMatch(tb->nextOf());
                        if (f)
                        {
                            result = new VarExp(e->loc, f, false);
                            result->type = f->type;
                            result = new AddrExp(e->loc, result, t);
                            return;
                        }
                    }
                }

                if (FuncDeclaration *f = isFuncAddress(e))
                {
                    if (f->checkForwardRef(e->loc))
                    {
                        result = new ErrorExp();
                        return;
                    }
                }

                visit((Expression *)e);
            }
            result->type = t;
        }

        void visit(TupleExp *e)
        {
            if (e->type->equals(t))
            {
                result = e;
                return;
            }

            TupleExp *te = (TupleExp *)e->copy();
            te->e0 = e->e0 ? e->e0->copy() : NULL;
            te->exps = (Expressions *)e->exps->copy();
            for (size_t i = 0; i < te->exps->length; i++)
            {
                Expression *ex = (*te->exps)[i];
                ex = ex->castTo(sc, t);
                (*te->exps)[i] = ex;
            }
            result = te;

            /* Questionable behavior: In here, result->type is not set to t.
             * Therefoe:
             *  TypeTuple!(int, int) values;
             *  auto values2 = cast(long)values;
             *  // typeof(values2) == TypeTuple!(int, int) !!
             *
             * Only when the casted tuple is immediately expanded, it would work.
             *  auto arr = [cast(long)values];
             *  // typeof(arr) == long[]
             */
        }

        void visit(ArrayLiteralExp *e)
        {
            if (e->type == t)
            {
                result = e;
                return;
            }
            ArrayLiteralExp *ae = e;
            Type *typeb = e->type->toBasetype();
            Type *tb = t->toBasetype();
            if ((tb->ty == Tarray || tb->ty == Tsarray) &&
                (typeb->ty == Tarray || typeb->ty == Tsarray))
            {
                if (tb->nextOf()->toBasetype()->ty == Tvoid && typeb->nextOf()->toBasetype()->ty != Tvoid)
                {
                    // Don't do anything to cast non-void[] to void[]
                }
                else if (typeb->ty == Tsarray && typeb->nextOf()->toBasetype()->ty == Tvoid)
                {
                    // Don't do anything for casting void[n] to others
                }
                else
                {
                    if (tb->ty == Tsarray)
                    {
                        TypeSArray *tsa = (TypeSArray *)tb;
                        if (e->elements->length != tsa->dim->toInteger())
                            goto L1;
                    }

                    ae = (ArrayLiteralExp *)e->copy();
                    if (e->basis)
                        ae->basis = e->basis->castTo(sc, tb->nextOf());
                    ae->elements = e->elements->copy();
                    for (size_t i = 0; i < e->elements->length; i++)
                    {
                        Expression *ex = (*e->elements)[i];
                        if (!ex)
                            continue;
                        ex = ex->castTo(sc, tb->nextOf());
                        (*ae->elements)[i] = ex;
                    }
                    ae->type = t;
                    result = ae;
                    return;
                }
            }
            else if (tb->ty == Tpointer && typeb->ty == Tsarray)
            {
                Type *tp = typeb->nextOf()->pointerTo();
                if (!tp->equals(ae->type))
                {
                    ae = (ArrayLiteralExp *)e->copy();
                    ae->type = tp;
                }
            }
            else if (tb->ty == Tvector &&
                (typeb->ty == Tarray || typeb->ty == Tsarray))
            {
                // Convert array literal to vector type
                TypeVector *tv = (TypeVector *)tb;
                TypeSArray *tbase = (TypeSArray *)tv->basetype;
                assert(tbase->ty == Tsarray);
                const size_t edim = e->elements->length;
                const size_t tbasedim = tbase->dim->toInteger();
                if (edim > tbasedim)
                    goto L1;

                ae = (ArrayLiteralExp *)e->copy();
                ae->type = tbase;   // Bugzilla 12642
                ae->elements = e->elements->copy();
                Type *telement = tv->elementType();
                for (size_t i = 0; i < edim; i++)
                {
                    Expression *ex = (*e->elements)[i];
                    ex = ex->castTo(sc, telement);
                    (*ae->elements)[i] = ex;
                }
                // Fill in the rest with the default initializer
                ae->elements->setDim(tbasedim);
                for (size_t i = edim; i < tbasedim; i++)
                {
                    Expression *ex = typeb->nextOf()->defaultInitLiteral(e->loc);
                    ex = ex->castTo(sc, telement);
                    (*ae->elements)[i] = ex;
                }
                Expression *ev = new VectorExp(e->loc, ae, tb);
                ev = expressionSemantic(ev, sc);
                result = ev;
                return;
            }
        L1:
            visit((Expression *)ae);
        }

        void visit(AssocArrayLiteralExp *e)
        {
            if (e->type == t)
            {
                result = e;
                return;
            }
            Type *typeb = e->type->toBasetype();
            Type *tb = t->toBasetype();
            if (tb->ty == Taarray && typeb->ty == Taarray &&
                tb->nextOf()->toBasetype()->ty != Tvoid)
            {
                AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)e->copy();
                ae->keys = e->keys->copy();
                ae->values = e->values->copy();
                assert(e->keys->length == e->values->length);
                for (size_t i = 0; i < e->keys->length; i++)
                {
                    Expression *ex = (*e->values)[i];
                    ex = ex->castTo(sc, tb->nextOf());
                    (*ae->values)[i] = ex;

                    ex = (*e->keys)[i];
                    ex = ex->castTo(sc, ((TypeAArray *)tb)->index);
                    (*ae->keys)[i] = ex;
                }
                ae->type = t;
                result = ae;
                return;
            }
            visit((Expression *)e);
        }

        void visit(SymOffExp *e)
        {
            if (e->type == t && !e->hasOverloads)
            {
                result = e;
                return;
            }
            Type *tb = t->toBasetype();
            Type *typeb = e->type->toBasetype();

            if (tb->equals(typeb))
            {
                result = e->copy();
                result->type = t;
                ((SymOffExp *)result)->hasOverloads = false;
                return;
            }

            // Look for pointers to functions where the functions are overloaded.
            if (e->hasOverloads &&
                typeb->ty == Tpointer && typeb->nextOf()->ty == Tfunction &&
                (tb->ty == Tpointer || tb->ty == Tdelegate) && tb->nextOf()->ty == Tfunction)
            {
                FuncDeclaration *f = e->var->isFuncDeclaration();
                f = f ? f->overloadExactMatch(tb->nextOf()) : NULL;
                if (f)
                {
                    if (tb->ty == Tdelegate)
                    {
                        if (f->needThis() && hasThis(sc))
                        {
                            result = new DelegateExp(e->loc, new ThisExp(e->loc), f, false);
                            result = expressionSemantic(result, sc);
                        }
                        else if (f->isNested())
                        {
                            result = new DelegateExp(e->loc, new IntegerExp(0), f, false);
                            result = expressionSemantic(result, sc);
                        }
                        else if (f->needThis())
                        {
                            e->error("no `this` to create delegate for %s", f->toChars());
                            result = new ErrorExp();
                            return;
                        }
                        else
                        {
                            e->error("cannot cast from function pointer to delegate");
                            result = new ErrorExp();
                            return;
                        }
                    }
                    else
                    {
                        result = new SymOffExp(e->loc, f, 0, false);
                        result->type = t;
                    }
                    f->tookAddressOf++;
                    return;
                }
            }

            if (FuncDeclaration *f = isFuncAddress(e))
            {
                if (f->checkForwardRef(e->loc))
                {
                    result = new ErrorExp();
                    return;
                }
            }

            visit((Expression *)e);
        }

        void visit(DelegateExp *e)
        {
            static const char msg[] = "cannot form delegate due to covariant return type";

            Type *tb = t->toBasetype();
            Type *typeb = e->type->toBasetype();
            if (!tb->equals(typeb) || e->hasOverloads)
            {
                // Look for delegates to functions where the functions are overloaded.
                if (typeb->ty == Tdelegate &&
                    tb->ty == Tdelegate)
                {
                    if (e->func)
                    {
                        FuncDeclaration *f = e->func->overloadExactMatch(tb->nextOf());
                        if (f)
                        {
                            int offset;
                            if (f->tintro && f->tintro->nextOf()->isBaseOf(f->type->nextOf(), &offset) && offset)
                                e->error("%s", msg);
                            if (f != e->func)    // if address not already marked as taken
                                f->tookAddressOf++;
                            result = new DelegateExp(e->loc, e->e1, f, false);
                            result->type = t;
                            return;
                        }
                        if (e->func->tintro)
                            e->error("%s", msg);
                    }
                }

                if (FuncDeclaration *f = isFuncAddress(e))
                {
                    if (f->checkForwardRef(e->loc))
                    {
                        result = new ErrorExp();
                        return;
                    }
                }

                visit((Expression *)e);
            }
            else
            {
                int offset;
                e->func->tookAddressOf++;
                if (e->func->tintro && e->func->tintro->nextOf()->isBaseOf(e->func->type->nextOf(), &offset) && offset)
                    e->error("%s", msg);
                result = e->copy();
                result->type = t;
            }
        }

        void visit(FuncExp *e)
        {
            //printf("FuncExp::castTo type = %s, t = %s\n", e->type->toChars(), t->toChars());
            FuncExp *fe;
            if (e->matchType(t, sc, &fe, 1) > MATCHnomatch)
            {
                result = fe;
                return;
            }
            visit((Expression *)e);
        }

        void visit(CondExp *e)
        {
            if (!e->type->equals(t))
            {
                result = new CondExp(e->loc, e->econd, e->e1->castTo(sc, t), e->e2->castTo(sc, t));
                result->type = t;
                return;
            }
            result = e;
        }

        void visit(CommaExp *e)
        {
            Expression *e2c = e->e2->castTo(sc, t);

            if (e2c != e->e2)
            {
                result = new CommaExp(e->loc, e->e1, e2c);
                result->type = e2c->type;
            }
            else
            {
                result = e;
                result->type = e->e2->type;
            }
        }

        void visit(SliceExp *e)
        {
            //printf("SliceExp::castTo e = %s, type = %s, t = %s\n", e->toChars(), e->type->toChars(), t->toChars());
            Type *typeb = e->type->toBasetype();
            Type *tb = t->toBasetype();
            if (e->type->equals(t) || typeb->ty != Tarray ||
                (tb->ty != Tarray && tb->ty != Tsarray))
            {
                visit((Expression *)e);
                return;
            }

            if (tb->ty == Tarray)
            {
                if (typeb->nextOf()->equivalent(tb->nextOf()))
                {
                    // T[] to const(T)[]
                    result = e->copy();
                    result->type = t;
                }
                else
                {
                    visit((Expression *)e);
                }
                return;
            }

            // Handle the cast from Tarray to Tsarray with CT-known slicing

            TypeSArray *tsa = (TypeSArray *)toStaticArrayType(e);
            if (tsa && tsa->size(e->loc) == tb->size(e->loc))
            {
                /* Match if the sarray sizes are equal:
                 *  T[a .. b] to const(T)[b-a]
                 *  T[a .. b] to U[dim] if (T.sizeof*(b-a) == U.sizeof*dim)
                 *
                 * If a SliceExp has Tsarray, it will become lvalue.
                 * That's handled in SliceExp::isLvalue and toLvalue
                 */
                result = e->copy();
                result->type = t;
                return;
            }
            if (tsa && tsa->dim->equals(((TypeSArray *)tb)->dim))
            {
                /* Match if the dimensions are equal
                 * with the implicit conversion of e->e1:
                 *  cast(float[2]) [2.0, 1.0, 0.0][0..2];
                 */
                Type *t1b = e->e1->type->toBasetype();
                if (t1b->ty == Tsarray)
                    t1b = tb->nextOf()->sarrayOf(((TypeSArray *)t1b)->dim->toInteger());
                else if (t1b->ty == Tarray)
                    t1b = tb->nextOf()->arrayOf();
                else if (t1b->ty == Tpointer)
                    t1b = tb->nextOf()->pointerTo();
                else
                    assert(0);
                if (e->e1->implicitConvTo(t1b) > MATCHnomatch)
                {
                    Expression *e1x = e->e1->implicitCastTo(sc, t1b);
                    assert(e1x->op != TOKerror);
                    e = (SliceExp *)e->copy();
                    e->e1 = e1x;
                    e->type = t;
                    result = e;
                    return;
                }
            }
            e->error("cannot cast expression %s of type %s to %s",
                e->toChars(), tsa ? tsa->toChars() : e->type->toChars(),
                t->toChars());
            result = new ErrorExp();
        }
    };

    CastTo v(sc, t);
    e->accept(&v);
    return v.result;
}

/* ==================== inferType ====================== */

/****************************************
 * Set type inference target
 *      t       Target type
 *      flag    1: don't put an error when inference fails
 */

Expression *inferType(Expression *e, Type *t, int flag)
{
    class InferType : public Visitor
    {
    public:
        Type *t;
        int flag;
        Expression *result;

        InferType(Type *t, int flag)
            : t(t), flag(flag)
        {
            result = NULL;
        }


        void visit(Expression *e)
        {
            result = e;
        }

        void visit(ArrayLiteralExp *ale)
        {
            Type *tb = t->toBasetype();
            if (tb->ty == Tarray || tb->ty == Tsarray)
            {
                Type *tn = tb->nextOf();
                if (ale->basis)
                    ale->basis = inferType(ale->basis, tn, flag);
                for (size_t i = 0; i < ale->elements->length; i++)
                {
                    Expression *e = (*ale->elements)[i];
                    if (e)
                    {
                        e = inferType(e, tn, flag);
                        (*ale->elements)[i] = e;
                    }
                }
            }
            result = ale;
        }

        void visit(AssocArrayLiteralExp *aale)
        {
            Type *tb = t->toBasetype();
            if (tb->ty == Taarray)
            {
                TypeAArray *taa = (TypeAArray *)tb;
                Type *ti = taa->index;
                Type *tv = taa->nextOf();
                for (size_t i = 0; i < aale->keys->length; i++)
                {
                    Expression *e = (*aale->keys)[i];
                    if (e)
                    {
                        e = inferType(e, ti, flag);
                        (*aale->keys)[i] = e;
                    }
                }
                for (size_t i = 0; i < aale->values->length; i++)
                {
                    Expression *e = (*aale->values)[i];
                    if (e)
                    {
                        e = inferType(e, tv, flag);
                        (*aale->values)[i] = e;
                    }
                }
            }
            result = aale;
        }

        void visit(FuncExp *fe)
        {
            //printf("FuncExp::inferType('%s'), to=%s\n", fe->type ? fe->type->toChars() : "null", t->toChars());
            if (t->ty == Tdelegate ||
                (t->ty == Tpointer && t->nextOf()->ty == Tfunction))
            {
                fe->fd->treq = t;
            }
            result = fe;
        }

        void visit(CondExp *ce)
        {
            Type *tb = t->toBasetype();
            ce->e1 = inferType(ce->e1, tb, flag);
            ce->e2 = inferType(ce->e2, tb, flag);
            result = ce;
        }
    };

    if (!t)
        return e;

    InferType v(t, flag);
    e->accept(&v);
    return v.result;
}

/* ==================== ====================== */

/****************************************
 * Scale addition/subtraction to/from pointer.
 */

Expression *scaleFactor(BinExp *be, Scope *sc)
{
    Type *t1b = be->e1->type->toBasetype();
    Type *t2b = be->e2->type->toBasetype();
    Expression *eoff;

    if (t1b->ty == Tpointer && t2b->isintegral())
    {
        // Need to adjust operator by the stride
        // Replace (ptr + int) with (ptr + (int * stride))
        Type *t = Type::tptrdiff_t;

        d_uns64 stride = t1b->nextOf()->size(be->loc);
        if (!t->equals(t2b))
            be->e2 = be->e2->castTo(sc, t);
        eoff = be->e2;
        be->e2 = new MulExp(be->loc, be->e2, new IntegerExp(Loc(), stride, t));
        be->e2->type = t;
        be->type = be->e1->type;
    }
    else if (t2b->ty == Tpointer && t1b->isintegral())
    {
        // Need to adjust operator by the stride
        // Replace (int + ptr) with (ptr + (int * stride))
        Type *t = Type::tptrdiff_t;
        Expression *e;

        d_uns64 stride = t2b->nextOf()->size(be->loc);
        if (!t->equals(t1b))
            e = be->e1->castTo(sc, t);
        else
            e = be->e1;
        eoff = e;
        e = new MulExp(be->loc, e, new IntegerExp(Loc(), stride, t));
        e->type = t;
        be->type = be->e2->type;
        be->e1 = be->e2;
        be->e2 = e;
    }
    else
        assert(0);

    if (sc->func && !sc->intypeof)
    {
        eoff = eoff->optimize(WANTvalue);
        if (eoff->op == TOKint64 && eoff->toInteger() == 0)
            ;
        else if (sc->func->setUnsafe())
        {
            be->error("pointer arithmetic not allowed in @safe functions");
            return new ErrorExp();
        }
    }

    return be;
}

/**************************************
 * Return true if e is an empty array literal with dimensionality
 * equal to or less than type of other array.
 * [], [[]], [[[]]], etc.
 * I.e., make sure that [1,2] is compatible with [],
 * [[1,2]] is compatible with [[]], etc.
 */
bool isVoidArrayLiteral(Expression *e, Type *other)
{
    while (e->op == TOKarrayliteral && e->type->ty == Tarray
        && (((ArrayLiteralExp *)e)->elements->length == 1))
    {
        ArrayLiteralExp *ale = (ArrayLiteralExp *)e;
        e = ale->getElement(0);
        if (other->ty == Tsarray || other->ty == Tarray)
            other = other->nextOf();
        else
            return false;
    }
    if (other->ty != Tsarray && other->ty != Tarray)
        return false;
    Type *t = e->type;
    return (e->op == TOKarrayliteral && t->ty == Tarray &&
        t->nextOf()->ty == Tvoid &&
        ((ArrayLiteralExp *)e)->elements->length == 0);
}

// used by deduceType()
Type *rawTypeMerge(Type *t1, Type *t2)
{
    if (t1->equals(t2))
        return t1;
    if (t1->equivalent(t2))
        return t1->castMod(MODmerge(t1->mod, t2->mod));

    Type *t1b = t1->toBasetype();
    Type *t2b = t2->toBasetype();
    if (t1b->equals(t2b))
        return t1b;
    if (t1b->equivalent(t2b))
        return t1b->castMod(MODmerge(t1b->mod, t2b->mod));

    TY ty = (TY)impcnvResult[t1b->ty][t2b->ty];
    if (ty != Terror)
        return Type::basic[ty];

    return NULL;
}

/**************************************
 * Combine types.
 * Output:
 *      *pt     merged type, if *pt is not NULL
 *      *pe1    rewritten e1
 *      *pe2    rewritten e2
 * Returns:
 *      true    success
 *      false   failed
 */

bool typeMerge(Scope *sc, TOK op, Type **pt, Expression **pe1, Expression **pe2)
{
    //printf("typeMerge() %s op %s\n", (*pe1)->toChars(), (*pe2)->toChars());

    MATCH m;
    Expression *e1 = *pe1;
    Expression *e2 = *pe2;
    Type *t1b = e1->type->toBasetype();
    Type *t2b = e2->type->toBasetype();

    if (op != TOKquestion ||
        (t1b->ty != t2b->ty && (t1b->isTypeBasic() && t2b->isTypeBasic())))
    {
        e1 = integralPromotions(e1, sc);
        e2 = integralPromotions(e2, sc);
    }

    Type *t1 = e1->type;
    Type *t2 = e2->type;
    assert(t1);
    Type *t = t1;

    /* The start type of alias this type recursion.
     * In following case, we should save A, and stop recursion
     * if it appears again.
     *      X -> Y -> [A] -> B -> A -> B -> ...
     */
    Type *att1 = NULL;
    Type *att2 = NULL;

    //if (t1) printf("\tt1 = %s\n", t1->toChars());
    //if (t2) printf("\tt2 = %s\n", t2->toChars());
    assert(t2);

    if (t1->mod != t2->mod &&
        t1->ty == Tenum && t2->ty == Tenum &&
        ((TypeEnum *)t1)->sym == ((TypeEnum *)t2)->sym)
    {
        unsigned char mod = MODmerge(t1->mod, t2->mod);
        t1 = t1->castMod(mod);
        t2 = t2->castMod(mod);
    }

Lagain:
    t1b = t1->toBasetype();
    t2b = t2->toBasetype();

    TY ty = (TY)impcnvResult[t1b->ty][t2b->ty];
    if (ty != Terror)
    {
        TY ty1 = (TY)impcnvType1[t1b->ty][t2b->ty];
        TY ty2 = (TY)impcnvType2[t1b->ty][t2b->ty];

        if (t1b->ty == ty1)     // if no promotions
        {
            if (t1->equals(t2))
            {
                t = t1;
                goto Lret;
            }

            if (t1b->equals(t2b))
            {
                t = t1b;
                goto Lret;
            }
        }

        t = Type::basic[ty];

        t1 = Type::basic[ty1];
        t2 = Type::basic[ty2];
        e1 = e1->castTo(sc, t1);
        e2 = e2->castTo(sc, t2);
        //printf("after typeCombine():\n");
        //print();
        //printf("ty = %d, ty1 = %d, ty2 = %d\n", ty, ty1, ty2);
        goto Lret;
    }

    t1 = t1b;
    t2 = t2b;

    if (t1->ty == Ttuple || t2->ty == Ttuple)
        goto Lincompatible;

    if (t1->equals(t2))
    {
        // merging can not result in new enum type
        if (t->ty == Tenum)
            t = t1b;
    }
    else if ((t1->ty == Tpointer && t2->ty == Tpointer) ||
             (t1->ty == Tdelegate && t2->ty == Tdelegate))
    {
        // Bring pointers to compatible type
        Type *t1n = t1->nextOf();
        Type *t2n = t2->nextOf();

        if (t1n->equals(t2n))
            ;
        else if (t1n->ty == Tvoid)      // pointers to void are always compatible
            t = t2;
        else if (t2n->ty == Tvoid)
            ;
        else if (t1->implicitConvTo(t2))
        {
            goto Lt2;
        }
        else if (t2->implicitConvTo(t1))
        {
            goto Lt1;
        }
        else if (t1n->ty == Tfunction && t2n->ty == Tfunction)
        {
            TypeFunction *tf1 = (TypeFunction *)t1n;
            TypeFunction *tf2 = (TypeFunction *)t2n;
            tf1->purityLevel();
            tf2->purityLevel();

            TypeFunction *d = (TypeFunction *)tf1->syntaxCopy();

            if (tf1->purity != tf2->purity)
                d->purity = PUREimpure;
            assert(d->purity != PUREfwdref);

            d->isnothrow = (tf1->isnothrow && tf2->isnothrow);
            d->isnogc    = (tf1->isnogc    && tf2->isnogc);

            if (tf1->trust == tf2->trust)
                d->trust = tf1->trust;
            else if (tf1->trust <= TRUSTsystem || tf2->trust <= TRUSTsystem)
                d->trust = TRUSTsystem;
            else
                d->trust = TRUSTtrusted;

            Type *tx = NULL;
            if (t1->ty == Tdelegate)
            {
                tx = new TypeDelegate(d);
            }
            else
                tx = d->pointerTo();

            tx = typeSemantic(tx, e1->loc, sc);

            if (t1->implicitConvTo(tx) && t2->implicitConvTo(tx))
            {
                t = tx;
                e1 = e1->castTo(sc, t);
                e2 = e2->castTo(sc, t);
                goto Lret;
            }
            goto Lincompatible;
        }
        else if (t1n->mod != t2n->mod)
        {
            if (!t1n->isImmutable() && !t2n->isImmutable() && t1n->isShared() != t2n->isShared())
                goto Lincompatible;
            unsigned char mod = MODmerge(t1n->mod, t2n->mod);
            t1 = t1n->castMod(mod)->pointerTo();
            t2 = t2n->castMod(mod)->pointerTo();
            t = t1;
            goto Lagain;
        }
        else if (t1n->ty == Tclass && t2n->ty == Tclass)
        {
            ClassDeclaration *cd1 = t1n->isClassHandle();
            ClassDeclaration *cd2 = t2n->isClassHandle();
            int offset;

            if (cd1->isBaseOf(cd2, &offset))
            {
                if (offset)
                    e2 = e2->castTo(sc, t);
            }
            else if (cd2->isBaseOf(cd1, &offset))
            {
                t = t2;
                if (offset)
                    e1 = e1->castTo(sc, t);
            }
            else
                goto Lincompatible;
        }
        else
        {
            t1 = t1n->constOf()->pointerTo();
            t2 = t2n->constOf()->pointerTo();
            if (t1->implicitConvTo(t2))
            {
                goto Lt2;
            }
            else if (t2->implicitConvTo(t1))
            {
                goto Lt1;
            }
            goto Lincompatible;
        }
    }
    else if ((t1->ty == Tsarray || t1->ty == Tarray) &&
             ((e2->op == TOKnull && t2->ty == Tpointer && t2->nextOf()->ty == Tvoid) ||
              (e2->op == TOKarrayliteral && t2->ty == Tsarray && t2->nextOf()->ty == Tvoid && ((TypeSArray *)t2)->dim->toInteger() == 0) ||
              (isVoidArrayLiteral(e2, t1)))
            )
    {
        /*  (T[n] op void*)   => T[]
         *  (T[]  op void*)   => T[]
         *  (T[n] op void[0]) => T[]
         *  (T[]  op void[0]) => T[]
         *  (T[n] op void[])  => T[]
         *  (T[]  op void[])  => T[]
         */
        goto Lx1;
    }
    else if ((t2->ty == Tsarray || t2->ty == Tarray) &&
             ((e1->op == TOKnull && t1->ty == Tpointer && t1->nextOf()->ty == Tvoid) ||
              (e1->op == TOKarrayliteral && t1->ty == Tsarray && t1->nextOf()->ty == Tvoid && ((TypeSArray *)t1)->dim->toInteger() == 0) ||
              (isVoidArrayLiteral(e1, t2)))
            )
    {
        /*  (void*   op T[n]) => T[]
         *  (void*   op T[])  => T[]
         *  (void[0] op T[n]) => T[]
         *  (void[0] op T[])  => T[]
         *  (void[]  op T[n]) => T[]
         *  (void[]  op T[])  => T[]
         */
        goto Lx2;
    }
    else if ((t1->ty == Tsarray || t1->ty == Tarray) &&
             (m = t1->implicitConvTo(t2)) != MATCHnomatch)
    {
        // Bugzilla 7285: Tsarray op [x, y, ...] should to be Tsarray
        // Bugzilla 14737: Tsarray ~ [x, y, ...] should to be Tarray
        if (t1->ty == Tsarray && e2->op == TOKarrayliteral && op != TOKcat)
            goto Lt1;
        if (m == MATCHconst &&
            (op == TOKaddass || op == TOKminass || op == TOKmulass ||
             op == TOKdivass || op == TOKmodass || op == TOKpowass ||
             op == TOKandass || op == TOKorass  || op == TOKxorass)
           )
        {
            // Don't make the lvalue const
            t = t2;
            goto Lret;
        }
        goto Lt2;
    }
    else if ((t2->ty == Tsarray || t2->ty == Tarray) && t2->implicitConvTo(t1))
    {
        // Bugzilla 7285 & 14737
        if (t2->ty == Tsarray && e1->op == TOKarrayliteral && op != TOKcat)
            goto Lt2;
        goto Lt1;
    }
    else if ((t1->ty == Tsarray || t1->ty == Tarray || t1->ty == Tpointer) &&
             (t2->ty == Tsarray || t2->ty == Tarray || t2->ty == Tpointer) &&
             t1->nextOf()->mod != t2->nextOf()->mod
            )
    {
        /* If one is mutable and the other invariant, then retry
         * with both of them as const
         */
        Type *t1n = t1->nextOf();
        Type *t2n = t2->nextOf();
        unsigned char mod;
        if (e1->op == TOKnull && e2->op != TOKnull)
            mod = t2n->mod;
        else if (e1->op != TOKnull && e2->op == TOKnull)
            mod = t1n->mod;
        else if (!t1n->isImmutable() && !t2n->isImmutable() && t1n->isShared() != t2n->isShared())
            goto Lincompatible;
        else
            mod = MODmerge(t1n->mod, t2n->mod);

        if (t1->ty == Tpointer)
            t1 = t1n->castMod(mod)->pointerTo();
        else
            t1 = t1n->castMod(mod)->arrayOf();

        if (t2->ty == Tpointer)
            t2 = t2n->castMod(mod)->pointerTo();
        else
            t2 = t2n->castMod(mod)->arrayOf();
        t = t1;
        goto Lagain;
    }
    else if (t1->ty == Tclass && t2->ty == Tclass)
    {
        if (t1->mod != t2->mod)
        {
            unsigned char mod;
            if (e1->op == TOKnull && e2->op != TOKnull)
                mod = t2->mod;
            else if (e1->op != TOKnull && e2->op == TOKnull)
                mod = t1->mod;
            else if (!t1->isImmutable() && !t2->isImmutable() && t1->isShared() != t2->isShared())
                goto Lincompatible;
            else
                mod = MODmerge(t1->mod, t2->mod);
            t1 = t1->castMod(mod);
            t2 = t2->castMod(mod);
            t = t1;
            goto Lagain;
        }
        goto Lcc;
    }
    else if (t1->ty == Tclass || t2->ty == Tclass)
    {
Lcc:
        while (1)
        {
            MATCH i1 = e2->implicitConvTo(t1);
            MATCH i2 = e1->implicitConvTo(t2);

            if (i1 && i2)
            {
                // We have the case of class vs. void*, so pick class
                if (t1->ty == Tpointer)
                    i1 = MATCHnomatch;
                else if (t2->ty == Tpointer)
                    i2 = MATCHnomatch;
            }

            if (i2)
            {
                e2 = e2->castTo(sc, t2);
                goto Lt2;
            }
            else if (i1)
            {
                e1 = e1->castTo(sc, t1);
                goto Lt1;
            }
            else if (t1->ty == Tclass && t2->ty == Tclass)
            {
                TypeClass *tc1 = (TypeClass *)t1;
                TypeClass *tc2 = (TypeClass *)t2;

                /* Pick 'tightest' type
                 */
                ClassDeclaration *cd1 = tc1->sym->baseClass;
                ClassDeclaration *cd2 = tc2->sym->baseClass;

                if (cd1 && cd2)
                {
                    t1 = cd1->type->castMod(t1->mod);
                    t2 = cd2->type->castMod(t2->mod);
                }
                else if (cd1)
                    t1 = cd1->type;
                else if (cd2)
                    t2 = cd2->type;
                else
                    goto Lincompatible;
            }
            else if (t1->ty == Tstruct && ((TypeStruct *)t1)->sym->aliasthis)
            {
                if (att1 && e1->type == att1)
                    goto Lincompatible;
                if (!att1 && e1->type->checkAliasThisRec())
                    att1 = e1->type;
                //printf("att tmerge(c || c) e1 = %s\n", e1->type->toChars());
                e1 = resolveAliasThis(sc, e1);
                t1 = e1->type;
                continue;
            }
            else if (t2->ty == Tstruct && ((TypeStruct *)t2)->sym->aliasthis)
            {
                if (att2 && e2->type == att2)
                    goto Lincompatible;
                if (!att2 && e2->type->checkAliasThisRec())
                    att2 = e2->type;
                //printf("att tmerge(c || c) e2 = %s\n", e2->type->toChars());
                e2 = resolveAliasThis(sc, e2);
                t2 = e2->type;
                continue;
            }
            else
                goto Lincompatible;
        }
    }
    else if (t1->ty == Tstruct && t2->ty == Tstruct)
    {
        if (t1->mod != t2->mod)
        {
            if (!t1->isImmutable() && !t2->isImmutable() && t1->isShared() != t2->isShared())
                goto Lincompatible;
            unsigned char mod = MODmerge(t1->mod, t2->mod);
            t1 = t1->castMod(mod);
            t2 = t2->castMod(mod);
            t = t1;
            goto Lagain;
        }

        TypeStruct *ts1 = (TypeStruct *)t1;
        TypeStruct *ts2 = (TypeStruct *)t2;
        if (ts1->sym != ts2->sym)
        {
            if (!ts1->sym->aliasthis && !ts2->sym->aliasthis)
                goto Lincompatible;

            MATCH i1 = MATCHnomatch;
            MATCH i2 = MATCHnomatch;

            Expression *e1b = NULL;
            Expression *e2b = NULL;
            if (ts2->sym->aliasthis)
            {
                if (att2 && e2->type == att2)
                    goto Lincompatible;
                if (!att2 && e2->type->checkAliasThisRec())
                    att2 = e2->type;
                //printf("att tmerge(s && s) e2 = %s\n", e2->type->toChars());
                e2b = resolveAliasThis(sc, e2);
                i1 = e2b->implicitConvTo(t1);
            }
            if (ts1->sym->aliasthis)
            {
                if (att1 && e1->type == att1)
                    goto Lincompatible;
                if (!att1 && e1->type->checkAliasThisRec())
                    att1 = e1->type;
                //printf("att tmerge(s && s) e1 = %s\n", e1->type->toChars());
                e1b = resolveAliasThis(sc, e1);
                i2 = e1b->implicitConvTo(t2);
            }
            if (i1 && i2)
                goto Lincompatible;

            if (i1)
                goto Lt1;
            else if (i2)
                goto Lt2;

            if (e1b)
            {
                e1 = e1b;
                t1 = e1b->type->toBasetype();
            }
            if (e2b)
            {
                e2 = e2b;
                t2 = e2b->type->toBasetype();
            }
            t = t1;
            goto Lagain;
        }
    }
    else if (t1->ty == Tstruct || t2->ty == Tstruct)
    {
        if (t1->ty == Tstruct && ((TypeStruct *)t1)->sym->aliasthis)
        {
            if (att1 && e1->type == att1)
                goto Lincompatible;
            if (!att1 && e1->type->checkAliasThisRec())
                att1 = e1->type;
            //printf("att tmerge(s || s) e1 = %s\n", e1->type->toChars());
            e1 = resolveAliasThis(sc, e1);
            t1 = e1->type;
            t = t1;
            goto Lagain;
        }
        if (t2->ty == Tstruct && ((TypeStruct *)t2)->sym->aliasthis)
        {
            if (att2 && e2->type == att2)
                goto Lincompatible;
            if (!att2 && e2->type->checkAliasThisRec())
                att2 = e2->type;
            //printf("att tmerge(s || s) e2 = %s\n", e2->type->toChars());
            e2 = resolveAliasThis(sc, e2);
            t2 = e2->type;
            t = t2;
            goto Lagain;
        }
        goto Lincompatible;
    }
    else if ((e1->op == TOKstring || e1->op == TOKnull) && e1->implicitConvTo(t2))
    {
        goto Lt2;
    }
    else if ((e2->op == TOKstring || e2->op == TOKnull) && e2->implicitConvTo(t1))
    {
        goto Lt1;
    }
    else if (t1->ty == Tsarray && t2->ty == Tsarray &&
             e2->implicitConvTo(t1->nextOf()->arrayOf()))
    {
     Lx1:
        t = t1->nextOf()->arrayOf();    // T[]
        e1 = e1->castTo(sc, t);
        e2 = e2->castTo(sc, t);
    }
    else if (t1->ty == Tsarray && t2->ty == Tsarray &&
             e1->implicitConvTo(t2->nextOf()->arrayOf()))
    {
     Lx2:
        t = t2->nextOf()->arrayOf();
        e1 = e1->castTo(sc, t);
        e2 = e2->castTo(sc, t);
    }
    else if (t1->ty == Tvector && t2->ty == Tvector)
    {
        // Bugzilla 13841, all vector types should have no common types between
        // different vectors, even though their sizes are same.
        TypeVector *tv1 = (TypeVector *)t1;
        TypeVector *tv2 = (TypeVector *)t2;
        if (!tv1->basetype->equals(tv2->basetype))
            goto Lincompatible;

        goto LmodCompare;
    }
    else if (t1->ty == Tvector && t2->ty != Tvector &&
             e2->implicitConvTo(t1))
    {
        e2 = e2->castTo(sc, t1);
        t2 = t1;
        t = t1;
        goto Lagain;
    }
    else if (t2->ty == Tvector && t1->ty != Tvector &&
             e1->implicitConvTo(t2))
    {
        e1 = e1->castTo(sc, t2);
        t1 = t2;
        t = t1;
        goto Lagain;
    }
    else if (t1->isintegral() && t2->isintegral())
    {
        if (t1->ty != t2->ty)
        {
            if (t1->ty == Tvector || t2->ty == Tvector)
                goto Lincompatible;
            e1 = integralPromotions(e1, sc);
            e2 = integralPromotions(e2, sc);
            t1 = e1->type;
            t2 = e2->type;
            goto Lagain;
        }
        assert(t1->ty == t2->ty);
LmodCompare:
        if (!t1->isImmutable() && !t2->isImmutable() && t1->isShared() != t2->isShared())
            goto Lincompatible;
        unsigned char mod = MODmerge(t1->mod, t2->mod);

        t1 = t1->castMod(mod);
        t2 = t2->castMod(mod);
        t = t1;
        e1 = e1->castTo(sc, t);
        e2 = e2->castTo(sc, t);
        goto Lagain;
    }
    else if (t1->ty == Tnull && t2->ty == Tnull)
    {
        unsigned char mod = MODmerge(t1->mod, t2->mod);

        t = t1->castMod(mod);
        e1 = e1->castTo(sc, t);
        e2 = e2->castTo(sc, t);
        goto Lret;
    }
    else if (t2->ty == Tnull &&
        (t1->ty == Tpointer || t1->ty == Taarray || t1->ty == Tarray))
    {
        goto Lt1;
    }
    else if (t1->ty == Tnull &&
        (t2->ty == Tpointer || t2->ty == Taarray || t2->ty == Tarray))
    {
        goto Lt2;
    }
    else if (t1->ty == Tarray && isBinArrayOp(op) && isArrayOpOperand(e1))
    {
        if (e2->implicitConvTo(t1->nextOf()))
        {
            // T[] op T
            // T[] op cast(T)U
            e2 = e2->castTo(sc, t1->nextOf());
            t = t1->nextOf()->arrayOf();
        }
        else if (t1->nextOf()->implicitConvTo(e2->type))
        {
            // (cast(T)U)[] op T    (Bugzilla 12780)
            // e1 is left as U[], it will be handled in arrayOp() later.
            t = e2->type->arrayOf();
        }
        else if (t2->ty == Tarray && isArrayOpOperand(e2))
        {
            if (t1->nextOf()->implicitConvTo(t2->nextOf()))
            {
                // (cast(T)U)[] op T[]  (Bugzilla 12780)
                // e1 is left as U[], it will be handled in arrayOp() later.
                t = t2->nextOf()->arrayOf();
            }
            else if (t2->nextOf()->implicitConvTo(t1->nextOf()))
            {
                // T[] op (cast(T)U)[]  (Bugzilla 12780)
                // e2 is left as U[], it will be handled in arrayOp() later.
                t = t1->nextOf()->arrayOf();
            }
            else
                goto Lincompatible;
        }
        else
            goto Lincompatible;
    }
    else if (t2->ty == Tarray && isBinArrayOp(op) && isArrayOpOperand(e2))
    {
        if (e1->implicitConvTo(t2->nextOf()))
        {
            // T op T[]
            // cast(T)U op T[]
            e1 = e1->castTo(sc, t2->nextOf());
            t = t2->nextOf()->arrayOf();
        }
        else if (t2->nextOf()->implicitConvTo(e1->type))
        {
            // T op (cast(T)U)[]    (Bugzilla 12780)
            // e2 is left as U[], it will be handled in arrayOp() later.
            t = e1->type->arrayOf();
        }
        else
            goto Lincompatible;

        //printf("test %s\n", Token::toChars(op));
        e1 = e1->optimize(WANTvalue);
        if (isCommutative(op) && e1->isConst())
        {
            /* Swap operands to minimize number of functions generated
             */
            //printf("swap %s\n", Token::toChars(op));
            Expression *tmp = e1;
            e1 = e2;
            e2 = tmp;
        }
    }
    else
    {
    Lincompatible:
        return false;
    }
Lret:
    if (!*pt)
        *pt = t;
    *pe1 = e1;
    *pe2 = e2;
    //print();
    return true;


Lt1:
    e2 = e2->castTo(sc, t1);
    t = t1;
    goto Lret;

Lt2:
    e1 = e1->castTo(sc, t2);
    t = t2;
    goto Lret;
}

/************************************
 * Bring leaves to common type.
 * Returns ErrorExp if error occurs. otherwise returns NULL.
 */

Expression *typeCombine(BinExp *be, Scope *sc)
{
    Type *t1 = be->e1->type->toBasetype();
    Type *t2 = be->e2->type->toBasetype();

    if (be->op == TOKmin || be->op == TOKadd)
    {
        // struct+struct, and class+class are errors
        if (t1->ty == Tstruct && t2->ty == Tstruct)
            goto Lerror;
        else if (t1->ty == Tclass && t2->ty == Tclass)
            goto Lerror;
        else if (t1->ty == Taarray && t2->ty == Taarray)
            goto Lerror;
    }

    if (!typeMerge(sc, be->op, &be->type, &be->e1, &be->e2))
        goto Lerror;
    // If the types have no value, return an error
    if (be->e1->op == TOKerror)
        return be->e1;
    if (be->e2->op == TOKerror)
        return be->e2;
    return NULL;

Lerror:
    Expression *ex = be->incompatibleTypes();
    if (ex->op == TOKerror)
        return ex;
    return new ErrorExp();
}

/***********************************
 * Do integral promotions (convertchk).
 * Don't convert <array of> to <pointer to>
 */

Expression *integralPromotions(Expression *e, Scope *sc)
{
    //printf("integralPromotions %s %s\n", e->toChars(), e->type->toChars());
    switch (e->type->toBasetype()->ty)
    {
        case Tvoid:
            e->error("void has no value");
            return new ErrorExp();

        case Tint8:
        case Tuns8:
        case Tint16:
        case Tuns16:
        case Tbool:
        case Tchar:
        case Twchar:
            e = e->castTo(sc, Type::tint32);
            break;

        case Tdchar:
            e = e->castTo(sc, Type::tuns32);
            break;
        default:
            break;
    }
    return e;
}

/***********************************
 * See if both types are arrays that can be compared
 * for equality. Return true if so.
 * If they are arrays, but incompatible, issue error.
 * This is to enable comparing things like an immutable
 * array with a mutable one.
 */

bool arrayTypeCompatible(Loc loc, Type *t1, Type *t2)
{
    t1 = t1->toBasetype()->merge2();
    t2 = t2->toBasetype()->merge2();

    if ((t1->ty == Tarray || t1->ty == Tsarray || t1->ty == Tpointer) &&
        (t2->ty == Tarray || t2->ty == Tsarray || t2->ty == Tpointer))
    {
        if (t1->nextOf()->implicitConvTo(t2->nextOf()) < MATCHconst &&
            t2->nextOf()->implicitConvTo(t1->nextOf()) < MATCHconst &&
            (t1->nextOf()->ty != Tvoid && t2->nextOf()->ty != Tvoid))
        {
            error(loc, "array equality comparison type mismatch, %s vs %s", t1->toChars(), t2->toChars());
        }
        return true;
    }
    return false;
}

/***********************************
 * See if both types are arrays that can be compared
 * for equality without any casting. Return true if so.
 * This is to enable comparing things like an immutable
 * array with a mutable one.
 */
bool arrayTypeCompatibleWithoutCasting(Type *t1, Type *t2)
{
    t1 = t1->toBasetype();
    t2 = t2->toBasetype();

    if ((t1->ty == Tarray || t1->ty == Tsarray || t1->ty == Tpointer) &&
        t2->ty == t1->ty)
    {
        if (t1->nextOf()->implicitConvTo(t2->nextOf()) >= MATCHconst ||
            t2->nextOf()->implicitConvTo(t1->nextOf()) >= MATCHconst)
            return true;
    }
    return false;
}

/******************************************************************/

/* Determine the integral ranges of an expression.
 * This is used to determine if implicit narrowing conversions will
 * be allowed.
 */

IntRange getIntRange(Expression *e)
{
    class IntRangeVisitor : public Visitor
    {
    public:
        IntRange range;

        void visit(Expression *e)
        {
            range = IntRange::fromType(e->type);
        }

        void visit(IntegerExp *e)
        {
            range = IntRange(SignExtendedNumber(e->getInteger())).cast(e->type);
        }

        void visit(CastExp *e)
        {
            range = getIntRange(e->e1).cast(e->type);
        }

        void visit(AddExp *e)
        {
            IntRange ir1 = getIntRange(e->e1);
            IntRange ir2 = getIntRange(e->e2);
            range = (ir1 + ir2).cast(e->type);
        }

        void visit(MinExp *e)
        {
            IntRange ir1 = getIntRange(e->e1);
            IntRange ir2 = getIntRange(e->e2);
            range = (ir1 - ir2).cast(e->type);
        }

        void visit(DivExp *e)
        {
            IntRange ir1 = getIntRange(e->e1);
            IntRange ir2 = getIntRange(e->e2);

            range = (ir1 / ir2).cast(e->type);
        }

        void visit(MulExp *e)
        {
            IntRange ir1 = getIntRange(e->e1);
            IntRange ir2 = getIntRange(e->e2);

            range = (ir1 * ir2).cast(e->type);
        }

        void visit(ModExp *e)
        {
            IntRange ir1 = getIntRange(e->e1);
            IntRange ir2 = getIntRange(e->e2);

            // Modding on 0 is invalid anyway.
            if (!ir2.absNeg().imin.negative)
            {
                visit((Expression *)e);
                return;
            }
            range = (ir1 % ir2).cast(e->type);
        }

        void visit(AndExp *e)
        {
            IntRange result;
            bool hasResult = false;
            result.unionOrAssign(getIntRange(e->e1) & getIntRange(e->e2), hasResult);

            assert(hasResult);
            range = result.cast(e->type);
        }

        void visit(OrExp *e)
        {
            IntRange result;
            bool hasResult = false;
            result.unionOrAssign(getIntRange(e->e1) | getIntRange(e->e2), hasResult);

            assert(hasResult);
            range = result.cast(e->type);
        }

        void visit(XorExp *e)
        {
            IntRange result;
            bool hasResult = false;
            result.unionOrAssign(getIntRange(e->e1) ^ getIntRange(e->e2), hasResult);

            assert(hasResult);
            range = result.cast(e->type);
        }

        void visit(ShlExp *e)
        {
            IntRange ir1 = getIntRange(e->e1);
            IntRange ir2 = getIntRange(e->e2);

            range = (ir1 << ir2).cast(e->type);
        }

        void visit(ShrExp *e)
        {
            IntRange ir1 = getIntRange(e->e1);
            IntRange ir2 = getIntRange(e->e2);

            range = (ir1 >> ir2).cast(e->type);
        }

        void visit(UshrExp *e)
        {
            IntRange ir1 = getIntRange(e->e1).castUnsigned(e->e1->type);
            IntRange ir2 = getIntRange(e->e2);

            range = (ir1 >> ir2).cast(e->type);
        }

        void visit(AssignExp *e)
        {
            range = getIntRange(e->e2).cast(e->type);
        }

        void visit(CondExp *e)
        {
            // No need to check e->econd; assume caller has called optimize()
            IntRange ir1 = getIntRange(e->e1);
            IntRange ir2 = getIntRange(e->e2);
            range = ir1.unionWith(ir2).cast(e->type);
        }

        void visit(VarExp *e)
        {
            Expression *ie;
            VarDeclaration* vd = e->var->isVarDeclaration();
            if (vd && vd->range)
                range = vd->range->cast(e->type);
            else if (vd && vd->_init && !vd->type->isMutable() &&
                (ie = vd->getConstInitializer()) != NULL)
                ie->accept(this);
            else
                visit((Expression *)e);
        }

        void visit(CommaExp *e)
        {
            e->e2->accept(this);
        }

        void visit(ComExp *e)
        {
            IntRange ir = getIntRange(e->e1);
            range = IntRange(SignExtendedNumber(~ir.imax.value, !ir.imax.negative),
                            SignExtendedNumber(~ir.imin.value, !ir.imin.negative)).cast(e->type);
        }

        void visit(NegExp *e)
        {
            IntRange ir = getIntRange(e->e1);
            range = (-ir).cast(e->type);
        }
    };

    IntRangeVisitor v;
    e->accept(&v);
    return v.range;
}
