/**
 * CTFE for expressions involving pointers, slices, array concatenation etc.
 *
 * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
 * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
 * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
 * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/ctfeexpr.d, _ctfeexpr.d)
 * Documentation:  https://dlang.org/phobos/dmd_ctfeexpr.html
 * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/ctfeexpr.d
 */

module dmd.ctfeexpr;

import core.stdc.stdio;
import core.stdc.stdlib;
import core.stdc.string;
import dmd.arraytypes;
import dmd.astenums;
import dmd.constfold;
import dmd.compiler;
import dmd.dclass;
import dmd.declaration;
import dmd.dinterpret;
import dmd.dstruct;
import dmd.dtemplate;
import dmd.errors;
import dmd.expression;
import dmd.func;
import dmd.globals;
import dmd.mtype;
import dmd.root.complex;
import dmd.root.ctfloat;
import dmd.root.port;
import dmd.root.rmem;
import dmd.tokens;
import dmd.visitor;


/***********************************************************
 * A reference to a class, or an interface. We need this when we
 * point to a base class (we must record what the type is).
 */
extern (C++) final class ClassReferenceExp : Expression
{
    StructLiteralExp value;

    extern (D) this(const ref Loc loc, StructLiteralExp lit, Type type)
    {
        super(loc, EXP.classReference, __traits(classInstanceSize, ClassReferenceExp));
        assert(lit && lit.sd && lit.sd.isClassDeclaration());
        this.value = lit;
        this.type = type;
    }

    ClassDeclaration originalClass()
    {
        return value.sd.isClassDeclaration();
    }

    // Return index of the field, or -1 if not found
    private int getFieldIndex(Type fieldtype, uint fieldoffset)
    {
        ClassDeclaration cd = originalClass();
        uint fieldsSoFar = 0;
        for (size_t j = 0; j < value.elements.dim; j++)
        {
            while (j - fieldsSoFar >= cd.fields.dim)
            {
                fieldsSoFar += cd.fields.dim;
                cd = cd.baseClass;
            }
            VarDeclaration v2 = cd.fields[j - fieldsSoFar];
            if (fieldoffset == v2.offset && fieldtype.size() == v2.type.size())
            {
                return cast(int)(value.elements.dim - fieldsSoFar - cd.fields.dim + (j - fieldsSoFar));
            }
        }
        return -1;
    }

    // Return index of the field, or -1 if not found
    // Same as getFieldIndex, but checks for a direct match with the VarDeclaration
    int findFieldIndexByName(VarDeclaration v)
    {
        ClassDeclaration cd = originalClass();
        size_t fieldsSoFar = 0;
        for (size_t j = 0; j < value.elements.dim; j++)
        {
            while (j - fieldsSoFar >= cd.fields.dim)
            {
                fieldsSoFar += cd.fields.dim;
                cd = cd.baseClass;
            }
            VarDeclaration v2 = cd.fields[j - fieldsSoFar];
            if (v == v2)
            {
                return cast(int)(value.elements.dim - fieldsSoFar - cd.fields.dim + (j - fieldsSoFar));
            }
        }
        return -1;
    }

    override void accept(Visitor v)
    {
        v.visit(this);
    }
}

/*************************
 * Same as getFieldIndex, but checks for a direct match with the VarDeclaration
 * Returns:
 *    index of the field, or -1 if not found
 */
int findFieldIndexByName(const StructDeclaration sd, const VarDeclaration v) pure
{
    foreach (i, field; sd.fields)
    {
        if (field == v)
            return cast(int)i;
    }
    return -1;
}

/***********************************************************
 * Fake class which holds the thrown exception.
 * Used for implementing exception handling.
 */
extern (C++) final class ThrownExceptionExp : Expression
{
    ClassReferenceExp thrown;   // the thing being tossed

    extern (D) this(const ref Loc loc, ClassReferenceExp victim)
    {
        super(loc, EXP.thrownException, __traits(classInstanceSize, ThrownExceptionExp));
        this.thrown = victim;
        this.type = victim.type;
    }

    override const(char)* toChars() const
    {
        return "CTFE ThrownException";
    }

    // Generate an error message when this exception is not caught
    extern (D) void generateUncaughtError()
    {
        UnionExp ue = void;
        Expression e = resolveSlice((*thrown.value.elements)[0], &ue);
        StringExp se = e.toStringExp();
        thrown.error("uncaught CTFE exception `%s(%s)`", thrown.type.toChars(), se ? se.toChars() : e.toChars());
        /* Also give the line where the throw statement was. We won't have it
         * in the case where the ThrowStatement is generated internally
         * (eg, in ScopeStatement)
         */
        if (loc.isValid() && !loc.equals(thrown.loc))
            .errorSupplemental(loc, "thrown from here");
    }

    override void accept(Visitor v)
    {
        v.visit(this);
    }
}

/***********************************************************
 * This type is only used by the interpreter.
 */
extern (C++) final class CTFEExp : Expression
{
    extern (D) this(EXP tok)
    {
        super(Loc.initial, tok, __traits(classInstanceSize, CTFEExp));
        type = Type.tvoid;
    }

    override const(char)* toChars() const
    {
        switch (op)
        {
        case EXP.cantExpression:
            return "<cant>";
        case EXP.voidExpression:
            return "cast(void)0";
        case EXP.showCtfeContext:
            return "<error>";
        case EXP.break_:
            return "<break>";
        case EXP.continue_:
            return "<continue>";
        case EXP.goto_:
            return "<goto>";
        default:
            assert(0);
        }
    }

    extern (D) __gshared CTFEExp cantexp;
    extern (D) __gshared CTFEExp voidexp;
    extern (D) __gshared CTFEExp breakexp;
    extern (D) __gshared CTFEExp continueexp;
    extern (D) __gshared CTFEExp gotoexp;
    /* Used when additional information is needed regarding
     * a ctfe error.
     */
    extern (D) __gshared CTFEExp showcontext;

    extern (D) static bool isCantExp(const Expression e)
    {
        return e && e.op == EXP.cantExpression;
    }

    extern (D) static bool isGotoExp(const Expression e)
    {
        return e && e.op == EXP.goto_;
    }
}

// True if 'e' is CTFEExp::cantexp, or an exception
bool exceptionOrCantInterpret(const Expression e)
{
    return e && (e.op == EXP.cantExpression || e.op == EXP.thrownException || e.op == EXP.showCtfeContext);
}

/************** Aggregate literals (AA/string/array/struct) ******************/
// Given expr, which evaluates to an array/AA/string literal,
// return true if it needs to be copied
bool needToCopyLiteral(const Expression expr)
{
    Expression e = cast()expr;
    for (;;)
    {
        switch (e.op)
        {
        case EXP.arrayLiteral:
            return e.isArrayLiteralExp().ownedByCtfe == OwnedBy.code;
        case EXP.assocArrayLiteral:
            return e.isAssocArrayLiteralExp().ownedByCtfe == OwnedBy.code;
        case EXP.structLiteral:
            return e.isStructLiteralExp().ownedByCtfe == OwnedBy.code;
        case EXP.string_:
        case EXP.this_:
        case EXP.variable:
            return false;
        case EXP.assign:
            return false;
        case EXP.index:
        case EXP.dotVariable:
        case EXP.slice:
        case EXP.cast_:
            e = e.isUnaExp().e1;
            continue;
        case EXP.concatenate:
            return needToCopyLiteral(e.isBinExp().e1) || needToCopyLiteral(e.isBinExp().e2);
        case EXP.concatenateAssign:
        case EXP.concatenateElemAssign:
        case EXP.concatenateDcharAssign:
            e = e.isBinExp().e2;
            continue;
        default:
            return false;
        }
    }
}

private Expressions* copyLiteralArray(Expressions* oldelems, Expression basis = null)
{
    if (!oldelems)
        return oldelems;
    incArrayAllocs();
    auto newelems = new Expressions(oldelems.dim);
    foreach (i, el; *oldelems)
    {
        (*newelems)[i] = copyLiteral(el ? el : basis).copy();
    }
    return newelems;
}

// Make a copy of the ArrayLiteral, AALiteral, String, or StructLiteral.
// This value will be used for in-place modification.
UnionExp copyLiteral(Expression e)
{
    UnionExp ue = void;
    if (auto se = e.isStringExp()) // syntaxCopy doesn't make a copy for StringExp!
    {
        char* s = cast(char*)mem.xcalloc(se.len + 1, se.sz);
        const slice = se.peekData();
        memcpy(s, slice.ptr, slice.length);
        emplaceExp!(StringExp)(&ue, se.loc, s[0 .. se.len * se.sz], se.len, se.sz);
        StringExp se2 = ue.exp().isStringExp();
        se2.committed = se.committed;
        se2.postfix = se.postfix;
        se2.type = se.type;
        se2.ownedByCtfe = OwnedBy.ctfe;
        return ue;
    }
    if (auto ale = e.isArrayLiteralExp())
    {
        auto elements = copyLiteralArray(ale.elements, ale.basis);

        emplaceExp!(ArrayLiteralExp)(&ue, e.loc, e.type, elements);

        ArrayLiteralExp r = ue.exp().isArrayLiteralExp();
        r.ownedByCtfe = OwnedBy.ctfe;
        return ue;
    }
    if (auto aae = e.isAssocArrayLiteralExp())
    {
        emplaceExp!(AssocArrayLiteralExp)(&ue, e.loc, copyLiteralArray(aae.keys), copyLiteralArray(aae.values));
        AssocArrayLiteralExp r = ue.exp().isAssocArrayLiteralExp();
        r.type = e.type;
        r.ownedByCtfe = OwnedBy.ctfe;
        return ue;
    }
    if (auto sle = e.isStructLiteralExp())
    {
        /* syntaxCopy doesn't work for struct literals, because of a nasty special
         * case: block assignment is permitted inside struct literals, eg,
         * an int[4] array can be initialized with a single int.
         */
        auto oldelems = sle.elements;
        auto newelems = new Expressions(oldelems.dim);
        foreach (i, ref el; *newelems)
        {
            // We need the struct definition to detect block assignment
            auto v = sle.sd.fields[i];
            auto m = (*oldelems)[i];

            // If it is a void assignment, use the default initializer
            if (!m)
                m = voidInitLiteral(v.type, v).copy();

            if (v.type.ty == Tarray || v.type.ty == Taarray)
            {
                // Don't have to copy array references
            }
            else
            {
                // Buzilla 15681: Copy the source element always.
                m = copyLiteral(m).copy();

                // Block assignment from inside struct literals
                if (v.type.ty != m.type.ty && v.type.ty == Tsarray)
                {
                    auto tsa = v.type.isTypeSArray();
                    auto len = cast(size_t)tsa.dim.toInteger();
                    m = createBlockDuplicatedArrayLiteral(&ue, e.loc, v.type, m, len);
                    if (m == ue.exp())
                        m = ue.copy();
                }
            }
            el = m;
        }
        emplaceExp!(StructLiteralExp)(&ue, e.loc, sle.sd, newelems, sle.stype);
        auto r = ue.exp().isStructLiteralExp();
        r.type = e.type;
        r.ownedByCtfe = OwnedBy.ctfe;
        r.origin = sle.origin;
        return ue;
    }
    if (e.op == EXP.function_ || e.op == EXP.delegate_ || e.op == EXP.symbolOffset || e.op == EXP.null_ || e.op == EXP.variable || e.op == EXP.dotVariable || e.op == EXP.int64 || e.op == EXP.float64 || e.op == EXP.char_ || e.op == EXP.complex80 || e.op == EXP.void_ || e.op == EXP.vector || e.op == EXP.typeid_)
    {
        // Simple value types
        // Keep e1 for DelegateExp and DotVarExp
        emplaceExp!(UnionExp)(&ue, e);
        Expression r = ue.exp();
        r.type = e.type;
        return ue;
    }
    if (auto se = e.isSliceExp())
    {
        if (se.type.toBasetype().ty == Tsarray)
        {
            // same with resolveSlice()
            if (se.e1.op == EXP.null_)
            {
                emplaceExp!(NullExp)(&ue, se.loc, se.type);
                return ue;
            }
            ue = Slice(se.type, se.e1, se.lwr, se.upr);
            auto r = ue.exp().isArrayLiteralExp();
            r.elements = copyLiteralArray(r.elements);
            r.ownedByCtfe = OwnedBy.ctfe;
            return ue;
        }
        else
        {
            // Array slices only do a shallow copy
            emplaceExp!(SliceExp)(&ue, e.loc, se.e1, se.lwr, se.upr);
            Expression r = ue.exp();
            r.type = e.type;
            return ue;
        }
    }
    if (isPointer(e.type))
    {
        // For pointers, we only do a shallow copy.
        if (auto ae = e.isAddrExp())
            emplaceExp!(AddrExp)(&ue, e.loc, ae.e1);
        else if (auto ie = e.isIndexExp())
            emplaceExp!(IndexExp)(&ue, e.loc, ie.e1, ie.e2);
        else if (auto dve = e.isDotVarExp())
        {
            emplaceExp!(DotVarExp)(&ue, e.loc, dve.e1, dve.var, dve.hasOverloads);
        }
        else
            assert(0);

        Expression r = ue.exp();
        r.type = e.type;
        return ue;
    }
    if (auto cre = e.isClassReferenceExp())
    {
        emplaceExp!(ClassReferenceExp)(&ue, e.loc, cre.value, e.type);
        return ue;
    }
    if (e.op == EXP.error)
    {
        emplaceExp!(UnionExp)(&ue, e);
        return ue;
    }
    e.error("CTFE internal error: literal `%s`", e.toChars());
    assert(0);
}

/* Deal with type painting.
 * Type painting is a major nuisance: we can't just set
 * e.type = type, because that would change the original literal.
 * But, we can't simply copy the literal either, because that would change
 * the values of any pointers.
 */
Expression paintTypeOntoLiteral(Type type, Expression lit)
{
    if (lit.type.equals(type))
        return lit;
    return paintTypeOntoLiteralCopy(type, lit).copy();
}

Expression paintTypeOntoLiteral(UnionExp* pue, Type type, Expression lit)
{
    if (lit.type.equals(type))
        return lit;
    *pue = paintTypeOntoLiteralCopy(type, lit);
    return pue.exp();
}

private UnionExp paintTypeOntoLiteralCopy(Type type, Expression lit)
{
    UnionExp ue;
    if (lit.type.equals(type))
    {
        emplaceExp!(UnionExp)(&ue, lit);
        return ue;
    }
    // If it is a cast to inout, retain the original type of the referenced part.
    if (type.hasWild())
    {
        emplaceExp!(UnionExp)(&ue, lit);
        ue.exp().type = type;
        return ue;
    }
    if (auto se = lit.isSliceExp())
    {
        emplaceExp!(SliceExp)(&ue, lit.loc, se.e1, se.lwr, se.upr);
    }
    else if (auto ie = lit.isIndexExp())
    {
        emplaceExp!(IndexExp)(&ue, lit.loc, ie.e1, ie.e2);
    }
    else if (lit.op == EXP.arrayLiteral)
    {
        emplaceExp!(SliceExp)(&ue, lit.loc, lit, ctfeEmplaceExp!IntegerExp(Loc.initial, 0, Type.tsize_t), ArrayLength(Type.tsize_t, lit).copy());
    }
    else if (lit.op == EXP.string_)
    {
        // For strings, we need to introduce another level of indirection
        emplaceExp!(SliceExp)(&ue, lit.loc, lit, ctfeEmplaceExp!IntegerExp(Loc.initial, 0, Type.tsize_t), ArrayLength(Type.tsize_t, lit).copy());
    }
    else if (auto aae = lit.isAssocArrayLiteralExp())
    {
        // TODO: we should be creating a reference to this AAExp, not
        // just a ref to the keys and values.
        OwnedBy wasOwned = aae.ownedByCtfe;
        emplaceExp!(AssocArrayLiteralExp)(&ue, lit.loc, aae.keys, aae.values);
        aae = ue.exp().isAssocArrayLiteralExp();
        aae.ownedByCtfe = wasOwned;
    }
    else
    {
        // Can't type paint from struct to struct*; this needs another
        // level of indirection
        if (lit.op == EXP.structLiteral && isPointer(type))
            lit.error("CTFE internal error: painting `%s`", type.toChars());
        ue = copyLiteral(lit);
    }
    ue.exp().type = type;
    return ue;
}

/*************************************
 * If e is a SliceExp, constant fold it.
 * Params:
 *      e = expression to resolve
 *      pue = if not null, store resulting expression here
 * Returns:
 *      resulting expression
 */
Expression resolveSlice(Expression e, UnionExp* pue = null)
{
    SliceExp se = e.isSliceExp();
    if (!se)
        return e;
    if (se.e1.op == EXP.null_)
        return se.e1;
    if (pue)
    {
        *pue = Slice(e.type, se.e1, se.lwr, se.upr);
        return pue.exp();
    }
    else
        return Slice(e.type, se.e1, se.lwr, se.upr).copy();
}

/* Determine the array length, without interpreting it.
 * e must be an array literal, or a slice
 * It's very wasteful to resolve the slice when we only
 * need the length.
 */
uinteger_t resolveArrayLength(Expression e)
{
    switch (e.op)
    {
        case EXP.vector:
            return e.isVectorExp().dim;

        case EXP.null_:
            return 0;

        case EXP.slice:
        {
            auto se = e.isSliceExp();
            const ilo = se.lwr.toInteger();
            const iup = se.upr.toInteger();
            return iup - ilo;
        }

        case EXP.string_:
            return e.isStringExp().len;

        case EXP.arrayLiteral:
        {
            const ale = e.isArrayLiteralExp();
            return ale.elements ? ale.elements.dim : 0;
        }

        case EXP.assocArrayLiteral:
        {
            return e.isAssocArrayLiteralExp().keys.dim;
        }

        default:
            assert(0);
    }
}

/******************************
 * Helper for NewExp
 * Create an array literal consisting of 'elem' duplicated 'dim' times.
 * Params:
 *      pue = where to store result
 *      loc = source location where the interpretation occurs
 *      type = target type of the result
 *      elem = the source of array element, it will be owned by the result
 *      dim = element number of the result
 * Returns:
 *      Constructed ArrayLiteralExp
 */
ArrayLiteralExp createBlockDuplicatedArrayLiteral(UnionExp* pue, const ref Loc loc, Type type, Expression elem, size_t dim)
{
    if (type.ty == Tsarray && type.nextOf().ty == Tsarray && elem.type.ty != Tsarray)
    {
        // If it is a multidimensional array literal, do it recursively
        auto tsa = type.nextOf().isTypeSArray();
        const len = cast(size_t)tsa.dim.toInteger();
        elem = createBlockDuplicatedArrayLiteral(pue, loc, type.nextOf(), elem, len);
        if (elem == pue.exp())
            elem = pue.copy();
    }

    // Buzilla 15681
    const tb = elem.type.toBasetype();
    const mustCopy = tb.ty == Tstruct || tb.ty == Tsarray;

    auto elements = new Expressions(dim);
    foreach (i, ref el; *elements)
    {
        el = mustCopy && i ? copyLiteral(elem).copy() : elem;
    }
    emplaceExp!(ArrayLiteralExp)(pue, loc, type, elements);
    auto ale = pue.exp().isArrayLiteralExp();
    ale.ownedByCtfe = OwnedBy.ctfe;
    return ale;
}

/******************************
 * Helper for NewExp
 * Create a string literal consisting of 'value' duplicated 'dim' times.
 */
StringExp createBlockDuplicatedStringLiteral(UnionExp* pue, const ref Loc loc, Type type, dchar value, size_t dim, ubyte sz)
{
    auto s = cast(char*)mem.xcalloc(dim, sz);
    foreach (elemi; 0 .. dim)
    {
        switch (sz)
        {
        case 1:
            s[elemi] = cast(char)value;
            break;
        case 2:
            (cast(wchar*)s)[elemi] = cast(wchar)value;
            break;
        case 4:
            (cast(dchar*)s)[elemi] = value;
            break;
        default:
            assert(0);
        }
    }
    emplaceExp!(StringExp)(pue, loc, s[0 .. dim * sz], dim, sz);
    auto se = pue.exp().isStringExp();
    se.type = type;
    se.committed = true;
    se.ownedByCtfe = OwnedBy.ctfe;
    return se;
}

// Return true if t is an AA
bool isAssocArray(Type t)
{
    return t.toBasetype().isTypeAArray() !is null;
}

// Given a template AA type, extract the corresponding built-in AA type
TypeAArray toBuiltinAAType(Type t)
{
    return t.toBasetype().isTypeAArray();
}

/************** TypeInfo operations ************************************/
// Return true if type is TypeInfo_Class
bool isTypeInfo_Class(const Type type)
{
    auto tc = cast()type.isTypeClass();
    return tc && (Type.dtypeinfo == tc.sym || Type.dtypeinfo.isBaseOf(tc.sym, null));
}

/************** Pointer operations ************************************/
// Return true if t is a pointer (not a function pointer)
bool isPointer(Type t)
{
    Type tb = t.toBasetype();
    return tb.ty == Tpointer && tb.nextOf().ty != Tfunction;
}

// For CTFE only. Returns true if 'e' is true or a non-null pointer.
bool isTrueBool(Expression e)
{
    return e.toBool().hasValue(true) || ((e.type.ty == Tpointer || e.type.ty == Tclass) && e.op != EXP.null_);
}

/* Is it safe to convert from srcPointee* to destPointee* ?
 * srcPointee is the genuine type (never void).
 * destPointee may be void.
 */
bool isSafePointerCast(Type srcPointee, Type destPointee)
{
    // It's safe to cast S** to D** if it's OK to cast S* to D*
    while (srcPointee.ty == Tpointer && destPointee.ty == Tpointer)
    {
        srcPointee = srcPointee.nextOf();
        destPointee = destPointee.nextOf();
    }
    // It's OK if both are the same (modulo const)
    if (srcPointee.constConv(destPointee))
        return true;

    // It's ok to cast from/to shared because CTFE is single threaded anyways
    if (srcPointee.unSharedOf() == destPointee.unSharedOf())
        return true;

    // It's OK if function pointers differ only in safe/pure/nothrow
    if (srcPointee.ty == Tfunction && destPointee.ty == Tfunction)
        return srcPointee.covariant(destPointee) == Covariant.yes ||
            destPointee.covariant(srcPointee) == Covariant.yes;
    // it's OK to cast to void*
    if (destPointee.ty == Tvoid)
        return true;
    // It's OK to cast from V[K] to void*
    if (srcPointee.ty == Taarray && destPointee == Type.tvoidptr)
        return true;
    // It's OK if they are the same size (static array of) integers, eg:
    //     int*     --> uint*
    //     int[5][] --> uint[5][]
    if (srcPointee.ty == Tsarray && destPointee.ty == Tsarray)
    {
        if (srcPointee.size() != destPointee.size())
            return false;
        srcPointee = srcPointee.baseElemOf();
        destPointee = destPointee.baseElemOf();
    }
    return srcPointee.isintegral() && destPointee.isintegral() && srcPointee.size() == destPointee.size();
}

Expression getAggregateFromPointer(Expression e, dinteger_t* ofs)
{
    *ofs = 0;
    if (auto ae = e.isAddrExp())
        e = ae.e1;
    if (auto soe = e.isSymOffExp())
        *ofs = soe.offset;
    if (auto dve = e.isDotVarExp())
    {
        auto ex = dve.e1;
        const v = dve.var.isVarDeclaration();
        assert(v);
        StructLiteralExp se = (ex.op == EXP.classReference)
            ? ex.isClassReferenceExp().value
            : ex.isStructLiteralExp();

        // We can't use getField, because it makes a copy
        const i = (ex.op == EXP.classReference)
            ? ex.isClassReferenceExp().getFieldIndex(e.type, v.offset)
            : se.getFieldIndex(e.type, v.offset);
        e = (*se.elements)[i];
    }
    if (auto ie = e.isIndexExp())
    {
        // Note that each AA element is part of its own memory block
        if ((ie.e1.type.ty == Tarray || ie.e1.type.ty == Tsarray || ie.e1.op == EXP.string_ || ie.e1.op == EXP.arrayLiteral) && ie.e2.op == EXP.int64)
        {
            *ofs = ie.e2.toInteger();
            return ie.e1;
        }
    }
    if (auto se = e.isSliceExp())
    {
        if (se && e.type.toBasetype().ty == Tsarray &&
           (se.e1.type.ty == Tarray || se.e1.type.ty == Tsarray || se.e1.op == EXP.string_ || se.e1.op == EXP.arrayLiteral) && se.lwr.op == EXP.int64)
        {
            *ofs = se.lwr.toInteger();
            return se.e1;
        }
    }

    // It can be a `null` disguised as a cast, e.g. `cast(void*)0`.
    if (auto ie = e.isIntegerExp())
        if (ie.type.ty == Tpointer && ie.getInteger() == 0)
            return new NullExp(ie.loc, e.type.nextOf());
    // Those casts are invalid, but let the rest of the code handle it,
    // as it could be something like `x !is null`, which doesn't need
    // to dereference the pointer, even if the pointer is `cast(void*)420`.

    return e;
}

/** Return true if agg1 and agg2 are pointers to the same memory block
 */
bool pointToSameMemoryBlock(Expression agg1, Expression agg2)
{
    if (agg1 == agg2)
        return true;
    // For integers cast to pointers, we regard them as non-comparable
    // unless they are identical. (This may be overly strict).
    if (agg1.op == EXP.int64 && agg2.op == EXP.int64 && agg1.toInteger() == agg2.toInteger())
    {
        return true;
    }
    // Note that type painting can occur with VarExp, so we
    // must compare the variables being pointed to.
    if (agg1.op == EXP.variable && agg2.op == EXP.variable && agg1.isVarExp().var == agg2.isVarExp().var)
    {
        return true;
    }
    if (agg1.op == EXP.symbolOffset && agg2.op == EXP.symbolOffset && agg1.isSymOffExp().var == agg2.isSymOffExp().var)
    {
        return true;
    }
    return false;
}

// return e1 - e2 as an integer, or error if not possible
Expression pointerDifference(UnionExp* pue, const ref Loc loc, Type type, Expression e1, Expression e2)
{
    dinteger_t ofs1, ofs2;
    Expression agg1 = getAggregateFromPointer(e1, &ofs1);
    Expression agg2 = getAggregateFromPointer(e2, &ofs2);
    if (agg1 == agg2)
    {
        Type pointee = (cast(TypePointer)agg1.type).next;
        const sz = pointee.size();
        emplaceExp!(IntegerExp)(pue, loc, (ofs1 - ofs2) * sz, type);
    }
    else if (agg1.op == EXP.string_ && agg2.op == EXP.string_ &&
             agg1.isStringExp().peekString().ptr == agg2.isStringExp().peekString().ptr)
    {
        Type pointee = (cast(TypePointer)agg1.type).next;
        const sz = pointee.size();
        emplaceExp!(IntegerExp)(pue, loc, (ofs1 - ofs2) * sz, type);
    }
    else if (agg1.op == EXP.symbolOffset && agg2.op == EXP.symbolOffset &&
             agg1.isSymOffExp().var == agg2.isSymOffExp().var)
    {
        emplaceExp!(IntegerExp)(pue, loc, ofs1 - ofs2, type);
    }
    else
    {
        error(loc, "`%s - %s` cannot be interpreted at compile time: cannot subtract pointers to two different memory blocks", e1.toChars(), e2.toChars());
        emplaceExp!(CTFEExp)(pue, EXP.cantExpression);
    }
    return pue.exp();
}

// Return eptr op e2, where eptr is a pointer, e2 is an integer,
// and op is EXP.add or EXP.min
Expression pointerArithmetic(UnionExp* pue, const ref Loc loc, EXP op, Type type, Expression eptr, Expression e2)
{
    if (eptr.type.nextOf().ty == Tvoid)
    {
        error(loc, "cannot perform arithmetic on `void*` pointers at compile time");
    Lcant:
        emplaceExp!(CTFEExp)(pue, EXP.cantExpression);
        return pue.exp();
    }
    if (eptr.op == EXP.address)
        eptr = eptr.isAddrExp().e1;
    dinteger_t ofs1;
    Expression agg1 = getAggregateFromPointer(eptr, &ofs1);
    if (agg1.op == EXP.symbolOffset)
    {
        if (agg1.isSymOffExp().var.type.ty != Tsarray)
        {
            error(loc, "cannot perform pointer arithmetic on arrays of unknown length at compile time");
            goto Lcant;
        }
    }
    else if (agg1.op != EXP.string_ && agg1.op != EXP.arrayLiteral)
    {
        error(loc, "cannot perform pointer arithmetic on non-arrays at compile time");
        goto Lcant;
    }
    dinteger_t ofs2 = e2.toInteger();
    Type pointee = (cast(TypeNext)agg1.type.toBasetype()).next;
    dinteger_t sz = pointee.size();
    sinteger_t indx;
    dinteger_t len;
    if (agg1.op == EXP.symbolOffset)
    {
        indx = ofs1 / sz;
        len = (cast(TypeSArray)agg1.isSymOffExp().var.type).dim.toInteger();
    }
    else
    {
        Expression dollar = ArrayLength(Type.tsize_t, agg1).copy();
        assert(!CTFEExp.isCantExp(dollar));
        indx = ofs1;
        len = dollar.toInteger();
    }
    if (op == EXP.add || op == EXP.addAssign || op == EXP.plusPlus)
        indx += ofs2 / sz;
    else if (op == EXP.min || op == EXP.minAssign || op == EXP.minusMinus)
        indx -= ofs2 / sz;
    else
    {
        error(loc, "CTFE internal error: bad pointer operation");
        goto Lcant;
    }
    if (indx < 0 || len < indx)
    {
        error(loc, "cannot assign pointer to index %lld inside memory block `[0..%lld]`", indx, len);
        goto Lcant;
    }
    if (agg1.op == EXP.symbolOffset)
    {
        emplaceExp!(SymOffExp)(pue, loc, agg1.isSymOffExp().var, indx * sz);
        SymOffExp se = pue.exp().isSymOffExp();
        se.type = type;
        return pue.exp();
    }
    if (agg1.op != EXP.arrayLiteral && agg1.op != EXP.string_)
    {
        error(loc, "CTFE internal error: pointer arithmetic `%s`", agg1.toChars());
        goto Lcant;
    }
    if (eptr.type.toBasetype().ty == Tsarray)
    {
        dinteger_t dim = (cast(TypeSArray)eptr.type.toBasetype()).dim.toInteger();
        // Create a CTFE pointer &agg1[indx .. indx+dim]
        auto se = ctfeEmplaceExp!SliceExp(loc, agg1,
                ctfeEmplaceExp!IntegerExp(loc, indx, Type.tsize_t),
                ctfeEmplaceExp!IntegerExp(loc, indx + dim, Type.tsize_t));
        se.type = type.toBasetype().nextOf();
        emplaceExp!(AddrExp)(pue, loc, se);
        pue.exp().type = type;
        return pue.exp();
    }
    // Create a CTFE pointer &agg1[indx]
    auto ofs = ctfeEmplaceExp!IntegerExp(loc, indx, Type.tsize_t);
    Expression ie = ctfeEmplaceExp!IndexExp(loc, agg1, ofs);
    ie.type = type.toBasetype().nextOf(); // https://issues.dlang.org/show_bug.cgi?id=13992
    emplaceExp!(AddrExp)(pue, loc, ie);
    pue.exp().type = type;
    return pue.exp();
}

// Return 1 if true, 0 if false
// -1 if comparison is illegal because they point to non-comparable memory blocks
int comparePointers(EXP op, Expression agg1, dinteger_t ofs1, Expression agg2, dinteger_t ofs2)
{
    if (pointToSameMemoryBlock(agg1, agg2))
    {
        int n;
        switch (op)
        {
        case EXP.lessThan:
            n = (ofs1 < ofs2);
            break;
        case EXP.lessOrEqual:
            n = (ofs1 <= ofs2);
            break;
        case EXP.greaterThan:
            n = (ofs1 > ofs2);
            break;
        case EXP.greaterOrEqual:
            n = (ofs1 >= ofs2);
            break;
        case EXP.identity:
        case EXP.equal:
            n = (ofs1 == ofs2);
            break;
        case EXP.notIdentity:
        case EXP.notEqual:
            n = (ofs1 != ofs2);
            break;
        default:
            assert(0);
        }
        return n;
    }
    const null1 = (agg1.op == EXP.null_);
    const null2 = (agg2.op == EXP.null_);
    int cmp;
    if (null1 || null2)
    {
        switch (op)
        {
        case EXP.lessThan:
            cmp = null1 && !null2;
            break;
        case EXP.greaterThan:
            cmp = !null1 && null2;
            break;
        case EXP.lessOrEqual:
            cmp = null1;
            break;
        case EXP.greaterOrEqual:
            cmp = null2;
            break;
        case EXP.identity:
        case EXP.equal:
        case EXP.notIdentity: // 'cmp' gets inverted below
        case EXP.notEqual:
            cmp = (null1 == null2);
            break;
        default:
            assert(0);
        }
    }
    else
    {
        switch (op)
        {
        case EXP.identity:
        case EXP.equal:
        case EXP.notIdentity: // 'cmp' gets inverted below
        case EXP.notEqual:
            cmp = 0;
            break;
        default:
            return -1; // memory blocks are different
        }
    }
    if (op == EXP.notIdentity || op == EXP.notEqual)
        cmp ^= 1;
    return cmp;
}

// True if conversion from type 'from' to 'to' involves a reinterpret_cast
// floating point -> integer or integer -> floating point
bool isFloatIntPaint(Type to, Type from)
{
    return from.size() == to.size() && (from.isintegral() && to.isfloating() || from.isfloating() && to.isintegral());
}

// Reinterpret float/int value 'fromVal' as a float/integer of type 'to'.
Expression paintFloatInt(UnionExp* pue, Expression fromVal, Type to)
{
    if (exceptionOrCantInterpret(fromVal))
        return fromVal;
    assert(to.size() == 4 || to.size() == 8);
    return Compiler.paintAsType(pue, fromVal, to);
}

/******** Constant folding, with support for CTFE ***************************/
/// Return true if non-pointer expression e can be compared
/// with >,is, ==, etc, using ctfeCmp, ctfeEqual, ctfeIdentity
bool isCtfeComparable(Expression e)
{
    if (e.op == EXP.slice)
        e = e.isSliceExp().e1;
    if (e.isConst() != 1)
    {
        if (e.op == EXP.null_ || e.op == EXP.string_ || e.op == EXP.function_ || e.op == EXP.delegate_ || e.op == EXP.arrayLiteral || e.op == EXP.structLiteral || e.op == EXP.assocArrayLiteral || e.op == EXP.classReference)
        {
            return true;
        }
        // https://issues.dlang.org/show_bug.cgi?id=14123
        // TypeInfo object is comparable in CTFE
        if (e.op == EXP.typeid_)
            return true;
        return false;
    }
    return true;
}

/// Map EXP comparison ops
private bool numCmp(N)(EXP op, N n1, N n2)
{
    switch (op)
    {
    case EXP.lessThan:
        return n1 < n2;
    case EXP.lessOrEqual:
        return n1 <= n2;
    case EXP.greaterThan:
        return n1 > n2;
    case EXP.greaterOrEqual:
        return n1 >= n2;

    default:
        assert(0);
    }
}

/// Returns cmp OP 0; where OP is ==, !=, <, >=, etc. Result is 0 or 1
bool specificCmp(EXP op, int rawCmp)
{
    return numCmp!int(op, rawCmp, 0);
}

/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1
bool intUnsignedCmp(EXP op, dinteger_t n1, dinteger_t n2)
{
    return numCmp!dinteger_t(op, n1, n2);
}

/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1
bool intSignedCmp(EXP op, sinteger_t n1, sinteger_t n2)
{
    return numCmp!sinteger_t(op, n1, n2);
}

/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1
bool realCmp(EXP op, real_t r1, real_t r2)
{
    // Don't rely on compiler, handle NAN arguments separately
    if (CTFloat.isNaN(r1) || CTFloat.isNaN(r2)) // if unordered
    {
        switch (op)
        {
        case EXP.lessThan:
        case EXP.lessOrEqual:
        case EXP.greaterThan:
        case EXP.greaterOrEqual:
            return false;

        default:
            assert(0);
        }
    }
    else
    {
        return numCmp!real_t(op, r1, r2);
    }
}

/* Conceptually the same as memcmp(e1, e2).
 * e1 and e2 may be strings, arrayliterals, or slices.
 * For string types, return <0 if e1 < e2, 0 if e1==e2, >0 if e1 > e2.
 * For all other types, return 0 if e1 == e2, !=0 if e1 != e2.
 * Returns:
 *      -1,0,1
 */
private int ctfeCmpArrays(const ref Loc loc, Expression e1, Expression e2, uinteger_t len)
{
    // Resolve slices, if necessary
    uinteger_t lo1 = 0;
    uinteger_t lo2 = 0;

    Expression x1 = e1;
    if (auto sle1 = x1.isSliceExp())
    {
        lo1 = sle1.lwr.toInteger();
        x1 = sle1.e1;
    }
    auto se1 = x1.isStringExp();
    auto ae1 = x1.isArrayLiteralExp();

    Expression x2 = e2;
    if (auto sle2 = x2.isSliceExp())
    {
        lo2 = sle2.lwr.toInteger();
        x2 = sle2.e1;
    }
    auto se2 = x2.isStringExp();
    auto ae2 = x2.isArrayLiteralExp();

    // Now both must be either EXP.arrayLiteral or EXP.string_
    if (se1 && se2)
        return sliceCmpStringWithString(se1, se2, cast(size_t)lo1, cast(size_t)lo2, cast(size_t)len);
    if (se1 && ae2)
        return sliceCmpStringWithArray(se1, ae2, cast(size_t)lo1, cast(size_t)lo2, cast(size_t)len);
    if (se2 && ae1)
        return -sliceCmpStringWithArray(se2, ae1, cast(size_t)lo2, cast(size_t)lo1, cast(size_t)len);
    assert(ae1 && ae2);
    // Comparing two array literals. This case is potentially recursive.
    // If they aren't strings, we just need an equality check rather than
    // a full cmp.
    const bool needCmp = ae1.type.nextOf().isintegral();
    foreach (size_t i; 0 .. cast(size_t)len)
    {
        Expression ee1 = (*ae1.elements)[cast(size_t)(lo1 + i)];
        Expression ee2 = (*ae2.elements)[cast(size_t)(lo2 + i)];
        if (needCmp)
        {
            const sinteger_t c = ee1.toInteger() - ee2.toInteger();
            if (c > 0)
                return 1;
            if (c < 0)
                return -1;
        }
        else
        {
            if (ctfeRawCmp(loc, ee1, ee2))
                return 1;
        }
    }
    return 0;
}

/* Given a delegate expression e, return .funcptr.
 * If e is NullExp, return NULL.
 */
private FuncDeclaration funcptrOf(Expression e)
{
    assert(e.type.ty == Tdelegate);
    if (auto de = e.isDelegateExp())
        return de.func;
    if (auto fe = e.isFuncExp())
        return fe.fd;
    assert(e.op == EXP.null_);
    return null;
}

private bool isArray(const Expression e)
{
    return e.op == EXP.arrayLiteral || e.op == EXP.string_ || e.op == EXP.slice || e.op == EXP.null_;
}

/*****
 * Params:
 *      loc = source file location
 *      e1 = left operand
 *      e2 = right operand
 *      identity = true for `is` identity comparisons
 * Returns:
 * For strings, return <0 if e1 < e2, 0 if e1==e2, >0 if e1 > e2.
 * For all other types, return 0 if e1 == e2, !=0 if e1 != e2.
 */
private int ctfeRawCmp(const ref Loc loc, Expression e1, Expression e2, bool identity = false)
{
    if (e1.op == EXP.classReference || e2.op == EXP.classReference)
    {
        if (e1.op == EXP.classReference && e2.op == EXP.classReference &&
            e1.isClassReferenceExp().value == e2.isClassReferenceExp().value)
            return 0;
        return 1;
    }
    if (e1.op == EXP.typeid_ && e2.op == EXP.typeid_)
    {
        // printf("e1: %s\n", e1.toChars());
        // printf("e2: %s\n", e2.toChars());
        Type t1 = isType(e1.isTypeidExp().obj);
        Type t2 = isType(e2.isTypeidExp().obj);
        assert(t1);
        assert(t2);
        return t1 != t2;
    }
    // null == null, regardless of type
    if (e1.op == EXP.null_ && e2.op == EXP.null_)
        return 0;
    if (e1.type.ty == Tpointer && e2.type.ty == Tpointer)
    {
        // Can only be an equality test.
        dinteger_t ofs1, ofs2;
        Expression agg1 = getAggregateFromPointer(e1, &ofs1);
        Expression agg2 = getAggregateFromPointer(e2, &ofs2);
        if ((agg1 == agg2) || (agg1.op == EXP.variable && agg2.op == EXP.variable && agg1.isVarExp().var == agg2.isVarExp().var))
        {
            if (ofs1 == ofs2)
                return 0;
        }
        return 1;
    }
    if (e1.type.ty == Tdelegate && e2.type.ty == Tdelegate)
    {
        // If .funcptr isn't the same, they are not equal
        if (funcptrOf(e1) != funcptrOf(e2))
            return 1;
        // If both are delegate literals, assume they have the
        // same closure pointer. TODO: We don't support closures yet!
        if (e1.op == EXP.function_ && e2.op == EXP.function_)
            return 0;
        assert(e1.op == EXP.delegate_ && e2.op == EXP.delegate_);
        // Same .funcptr. Do they have the same .ptr?
        Expression ptr1 = e1.isDelegateExp().e1;
        Expression ptr2 = e2.isDelegateExp().e1;
        dinteger_t ofs1, ofs2;
        Expression agg1 = getAggregateFromPointer(ptr1, &ofs1);
        Expression agg2 = getAggregateFromPointer(ptr2, &ofs2);
        // If they are EXP.variable, it means they are FuncDeclarations
        if ((agg1 == agg2 && ofs1 == ofs2) || (agg1.op == EXP.variable && agg2.op == EXP.variable && agg1.isVarExp().var == agg2.isVarExp().var))
        {
            return 0;
        }
        return 1;
    }
    if (isArray(e1) && isArray(e2))
    {
        const uinteger_t len1 = resolveArrayLength(e1);
        const uinteger_t len2 = resolveArrayLength(e2);
        // workaround for dmc optimizer bug calculating wrong len for
        // uinteger_t len = (len1 < len2 ? len1 : len2);
        // if (len == 0) ...
        if (len1 > 0 && len2 > 0)
        {
            const uinteger_t len = (len1 < len2 ? len1 : len2);
            const int res = ctfeCmpArrays(loc, e1, e2, len);
            if (res != 0)
                return res;
        }
        return cast(int)(len1 - len2);
    }
    if (e1.type.isintegral())
    {
        return e1.toInteger() != e2.toInteger();
    }
    if (e1.type.isreal() || e1.type.isimaginary())
    {
        real_t r1 = e1.type.isreal() ? e1.toReal() : e1.toImaginary();
        real_t r2 = e1.type.isreal() ? e2.toReal() : e2.toImaginary();
        if (identity)
            return !CTFloat.isIdentical(r1, r2);
        if (CTFloat.isNaN(r1) || CTFloat.isNaN(r2)) // if unordered
        {
            return 1;   // they are not equal
        }
        else
        {
            return (r1 != r2);
        }
    }
    else if (e1.type.iscomplex())
    {
        auto c1 = e1.toComplex();
        auto c2 = e2.toComplex();
        if (identity)
        {
            return !RealIdentical(c1.re, c2.re) && !RealIdentical(c1.im, c2.im);
        }
        return c1 != c2;
    }
    if (e1.op == EXP.structLiteral && e2.op == EXP.structLiteral)
    {
        StructLiteralExp es1 = e1.isStructLiteralExp();
        StructLiteralExp es2 = e2.isStructLiteralExp();
        // For structs, we only need to return 0 or 1 (< and > aren't legal).
        if (es1.sd != es2.sd)
            return 1;
        else if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim))
            return 0; // both arrays are empty
        else if (!es1.elements || !es2.elements)
            return 1;
        else if (es1.elements.dim != es2.elements.dim)
            return 1;
        else
        {
            foreach (size_t i; 0 .. es1.elements.dim)
            {
                Expression ee1 = (*es1.elements)[i];
                Expression ee2 = (*es2.elements)[i];

                // https://issues.dlang.org/show_bug.cgi?id=16284
                if (ee1.op == EXP.void_ && ee2.op == EXP.void_) // if both are VoidInitExp
                    continue;

                if (ee1 == ee2)
                    continue;
                if (!ee1 || !ee2)
                    return 1;
                const int cmp = ctfeRawCmp(loc, ee1, ee2, identity);
                if (cmp)
                    return 1;
            }
            return 0; // All elements are equal
        }
    }
    if (e1.op == EXP.assocArrayLiteral && e2.op == EXP.assocArrayLiteral)
    {
        AssocArrayLiteralExp es1 = e1.isAssocArrayLiteralExp();
        AssocArrayLiteralExp es2 = e2.isAssocArrayLiteralExp();
        size_t dim = es1.keys.dim;
        if (es2.keys.dim != dim)
            return 1;
        bool* used = cast(bool*)mem.xmalloc(bool.sizeof * dim);
        memset(used, 0, bool.sizeof * dim);
        foreach (size_t i; 0 .. dim)
        {
            Expression k1 = (*es1.keys)[i];
            Expression v1 = (*es1.values)[i];
            Expression v2 = null;
            foreach (size_t j; 0 .. dim)
            {
                if (used[j])
                    continue;
                Expression k2 = (*es2.keys)[j];
                if (ctfeRawCmp(loc, k1, k2, identity))
                    continue;
                used[j] = true;
                v2 = (*es2.values)[j];
                break;
            }
            if (!v2 || ctfeRawCmp(loc, v1, v2, identity))
            {
                mem.xfree(used);
                return 1;
            }
        }
        mem.xfree(used);
        return 0;
    }
    else if (e1.op == EXP.assocArrayLiteral && e2.op == EXP.null_)
    {
        return e1.isAssocArrayLiteralExp.keys.dim != 0;
    }
    else if (e1.op == EXP.null_ && e2.op == EXP.assocArrayLiteral)
    {
        return e2.isAssocArrayLiteralExp.keys.dim != 0;
    }

    error(loc, "CTFE internal error: bad compare of `%s` and `%s`", e1.toChars(), e2.toChars());
    assert(0);
}

/// Evaluate ==, !=.  Resolves slices before comparing. Returns 0 or 1
bool ctfeEqual(const ref Loc loc, EXP op, Expression e1, Expression e2)
{
    return !ctfeRawCmp(loc, e1, e2) ^ (op == EXP.notEqual);
}

/// Evaluate is, !is.  Resolves slices before comparing. Returns 0 or 1
bool ctfeIdentity(const ref Loc loc, EXP op, Expression e1, Expression e2)
{
    //printf("ctfeIdentity %s %s\n", e1.toChars(), e2.toChars());
    //printf("ctfeIdentity op = '%s', e1 = %s %s, e2 = %s %s\n", EXPtoString(op).ptr,
    //    EXPtoString(e1.op).ptr, e1.toChars(), EXPtoString(e2.op).ptr, e1.toChars());
    bool cmp;
    if (e1.op == EXP.null_)
    {
        cmp = (e2.op == EXP.null_);
    }
    else if (e2.op == EXP.null_)
    {
        cmp = false;
    }
    else if (e1.op == EXP.symbolOffset && e2.op == EXP.symbolOffset)
    {
        SymOffExp es1 = e1.isSymOffExp();
        SymOffExp es2 = e2.isSymOffExp();
        cmp = (es1.var == es2.var && es1.offset == es2.offset);
    }
    else if (e1.type.isreal())
        cmp = CTFloat.isIdentical(e1.toReal(), e2.toReal());
    else if (e1.type.isimaginary())
        cmp = RealIdentical(e1.toImaginary(), e2.toImaginary());
    else if (e1.type.iscomplex())
    {
        complex_t v1 = e1.toComplex();
        complex_t v2 = e2.toComplex();
        cmp = RealIdentical(creall(v1), creall(v2)) && RealIdentical(cimagl(v1), cimagl(v1));
    }
    else
    {
        cmp = !ctfeRawCmp(loc, e1, e2, true);
    }
    if (op == EXP.notIdentity || op == EXP.notEqual)
        cmp ^= true;
    return cmp;
}

/// Evaluate >,<=, etc. Resolves slices before comparing. Returns 0 or 1
bool ctfeCmp(const ref Loc loc, EXP op, Expression e1, Expression e2)
{
    Type t1 = e1.type.toBasetype();
    Type t2 = e2.type.toBasetype();

    if (t1.isString() && t2.isString())
        return specificCmp(op, ctfeRawCmp(loc, e1, e2));
    else if (t1.isreal())
        return realCmp(op, e1.toReal(), e2.toReal());
    else if (t1.isimaginary())
        return realCmp(op, e1.toImaginary(), e2.toImaginary());
    else if (t1.isunsigned() || t2.isunsigned())
        return intUnsignedCmp(op, e1.toInteger(), e2.toInteger());
    else
        return intSignedCmp(op, e1.toInteger(), e2.toInteger());
}

UnionExp ctfeCat(const ref Loc loc, Type type, Expression e1, Expression e2)
{
    Type t1 = e1.type.toBasetype();
    Type t2 = e2.type.toBasetype();
    UnionExp ue;
    if (e2.op == EXP.string_ && e1.op == EXP.arrayLiteral && t1.nextOf().isintegral())
    {
        // [chars] ~ string => string (only valid for CTFE)
        StringExp es1 = e2.isStringExp();
        ArrayLiteralExp es2 = e1.isArrayLiteralExp();
        const len = es1.len + es2.elements.dim;
        const sz = es1.sz;
        void* s = mem.xmalloc((len + 1) * sz);
        const data1 = es1.peekData();
        memcpy(cast(char*)s + sz * es2.elements.dim, data1.ptr, data1.length);
        foreach (size_t i; 0 .. es2.elements.dim)
        {
            Expression es2e = (*es2.elements)[i];
            if (es2e.op != EXP.int64)
            {
                emplaceExp!(CTFEExp)(&ue, EXP.cantExpression);
                return ue;
            }
            dinteger_t v = es2e.toInteger();
            Port.valcpy(cast(char*)s + i * sz, v, sz);
        }
        // Add terminating 0
        memset(cast(char*)s + len * sz, 0, sz);
        emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz);
        StringExp es = ue.exp().isStringExp();
        es.committed = 0;
        es.type = type;
        return ue;
    }
    if (e1.op == EXP.string_ && e2.op == EXP.arrayLiteral && t2.nextOf().isintegral())
    {
        // string ~ [chars] => string (only valid for CTFE)
        // Concatenate the strings
        StringExp es1 = e1.isStringExp();
        ArrayLiteralExp es2 = e2.isArrayLiteralExp();
        const len = es1.len + es2.elements.dim;
        const sz = es1.sz;
        void* s = mem.xmalloc((len + 1) * sz);
        auto slice = es1.peekData();
        memcpy(s, slice.ptr, slice.length);
        foreach (size_t i; 0 .. es2.elements.dim)
        {
            Expression es2e = (*es2.elements)[i];
            if (es2e.op != EXP.int64)
            {
                emplaceExp!(CTFEExp)(&ue, EXP.cantExpression);
                return ue;
            }
            const v = es2e.toInteger();
            Port.valcpy(cast(char*)s + (es1.len + i) * sz, v, sz);
        }
        // Add terminating 0
        memset(cast(char*)s + len * sz, 0, sz);
        emplaceExp!(StringExp)(&ue, loc, s[0 .. len * sz], len, sz);
        StringExp es = ue.exp().isStringExp();
        es.sz = sz;
        es.committed = 0; //es1.committed;
        es.type = type;
        return ue;
    }
    if (e1.op == EXP.arrayLiteral && e2.op == EXP.arrayLiteral && t1.nextOf().equals(t2.nextOf()))
    {
        //  [ e1 ] ~ [ e2 ] ---> [ e1, e2 ]
        ArrayLiteralExp es1 = e1.isArrayLiteralExp();
        ArrayLiteralExp es2 = e2.isArrayLiteralExp();
        emplaceExp!(ArrayLiteralExp)(&ue, es1.loc, type, copyLiteralArray(es1.elements));
        es1 = ue.exp().isArrayLiteralExp();
        es1.elements.insert(es1.elements.dim, copyLiteralArray(es2.elements));
        return ue;
    }
    if (e1.op == EXP.arrayLiteral && e2.op == EXP.null_ && t1.nextOf().equals(t2.nextOf()))
    {
        //  [ e1 ] ~ null ----> [ e1 ].dup
        ue = paintTypeOntoLiteralCopy(type, copyLiteral(e1).copy());
        return ue;
    }
    if (e1.op == EXP.null_ && e2.op == EXP.arrayLiteral && t1.nextOf().equals(t2.nextOf()))
    {
        //  null ~ [ e2 ] ----> [ e2 ].dup
        ue = paintTypeOntoLiteralCopy(type, copyLiteral(e2).copy());
        return ue;
    }
    ue = Cat(loc, type, e1, e2);
    return ue;
}

/*  Given an AA literal 'ae', and a key 'e2':
 *  Return ae[e2] if present, or NULL if not found.
 */
Expression findKeyInAA(const ref Loc loc, AssocArrayLiteralExp ae, Expression e2)
{
    /* Search the keys backwards, in case there are duplicate keys
     */
    for (size_t i = ae.keys.dim; i;)
    {
        --i;
        Expression ekey = (*ae.keys)[i];
        const int eq = ctfeEqual(loc, EXP.equal, ekey, e2);
        if (eq)
        {
            return (*ae.values)[i];
        }
    }
    return null;
}

/* Same as for constfold.Index, except that it only works for static arrays,
 * dynamic arrays, and strings. We know that e1 is an
 * interpreted CTFE expression, so it cannot have side-effects.
 */
Expression ctfeIndex(UnionExp* pue, const ref Loc loc, Type type, Expression e1, uinteger_t indx)
{
    //printf("ctfeIndex(e1 = %s)\n", e1.toChars());
    assert(e1.type);
    if (auto es1 = e1.isStringExp())
    {
        if (indx >= es1.len)
        {
            error(loc, "string index %llu is out of bounds `[0 .. %llu]`", indx, cast(ulong)es1.len);
            return CTFEExp.cantexp;
        }
        emplaceExp!IntegerExp(pue, loc, es1.getCodeUnit(cast(size_t) indx), type);
        return pue.exp();
    }

    if (auto ale = e1.isArrayLiteralExp())
    {
        if (indx >= ale.elements.dim)
        {
            error(loc, "array index %llu is out of bounds `%s[0 .. %llu]`", indx, e1.toChars(), cast(ulong)ale.elements.dim);
            return CTFEExp.cantexp;
        }
        Expression e = (*ale.elements)[cast(size_t)indx];
        return paintTypeOntoLiteral(pue, type, e);
    }

    assert(0);
}

Expression ctfeCast(UnionExp* pue, const ref Loc loc, Type type, Type to, Expression e, bool explicitCast = false)
{
    Expression paint()
    {
        return paintTypeOntoLiteral(pue, to, e);
    }

    if (e.op == EXP.null_)
        return paint();

    if (e.op == EXP.classReference)
    {
        // Disallow reinterpreting class casts. Do this by ensuring that
        // the original class can implicitly convert to the target class.
        // Also do not check 'alias this' for explicit cast expressions.
        auto tclass = e.isClassReferenceExp().originalClass().type.isTypeClass();
        auto match = explicitCast ? tclass.implicitConvToWithoutAliasThis(to.mutableOf())
                                  : tclass.implicitConvTo(to.mutableOf());
        if (match)
            return paint();
        else
        {
            emplaceExp!(NullExp)(pue, loc, to);
            return pue.exp();
        }
    }

    // Allow TypeInfo type painting
    if (isTypeInfo_Class(e.type) && e.type.implicitConvTo(to))
        return paint();

    // Allow casting away const for struct literals
    if (e.op == EXP.structLiteral && e.type.toBasetype().castMod(0) == to.toBasetype().castMod(0))
        return paint();

    Expression r;
    if (e.type.equals(type) && type.equals(to))
    {
        // necessary not to change e's address for pointer comparisons
        r = e;
    }
    else if (to.toBasetype().ty == Tarray &&
             type.toBasetype().ty == Tarray &&
             to.toBasetype().nextOf().size() == type.toBasetype().nextOf().size())
    {
        // https://issues.dlang.org/show_bug.cgi?id=12495
        // Array reinterpret casts: eg. string to immutable(ubyte)[]
        return paint();
    }
    else
    {
        *pue = Cast(loc, type, to, e);
        r = pue.exp();
    }

    if (CTFEExp.isCantExp(r))
        error(loc, "cannot cast `%s` to `%s` at compile time", e.toChars(), to.toChars());

    if (auto ae = e.isArrayLiteralExp())
        ae.ownedByCtfe = OwnedBy.ctfe;

    if (auto se = e.isStringExp())
        se.ownedByCtfe = OwnedBy.ctfe;

    return r;
}

/******** Assignment helper functions ***************************/
/* Set dest = src, where both dest and src are container value literals
 * (ie, struct literals, or static arrays (can be an array literal or a string))
 * Assignment is recursively in-place.
 * Purpose: any reference to a member of 'dest' will remain valid after the
 * assignment.
 */
void assignInPlace(Expression dest, Expression src)
{
    if (!(dest.op == EXP.structLiteral || dest.op == EXP.arrayLiteral || dest.op == EXP.string_))
    {
        printf("invalid op %d %d\n", src.op, dest.op);
        assert(0);
    }
    Expressions* oldelems;
    Expressions* newelems;
    if (dest.op == EXP.structLiteral)
    {
        assert(dest.op == src.op);
        oldelems = dest.isStructLiteralExp().elements;
        newelems = src.isStructLiteralExp().elements;
        auto sd = dest.isStructLiteralExp().sd;
        const nfields = sd.nonHiddenFields();
        const nvthis = sd.fields.dim - nfields;
        if (nvthis && oldelems.dim >= nfields && oldelems.dim < newelems.dim)
            foreach (_; 0 .. newelems.dim - oldelems.dim)
                oldelems.push(null);
    }
    else if (dest.op == EXP.arrayLiteral && src.op == EXP.arrayLiteral)
    {
        oldelems = dest.isArrayLiteralExp().elements;
        newelems = src.isArrayLiteralExp().elements;
    }
    else if (dest.op == EXP.string_ && src.op == EXP.string_)
    {
        sliceAssignStringFromString(dest.isStringExp(), src.isStringExp(), 0);
        return;
    }
    else if (dest.op == EXP.arrayLiteral && src.op == EXP.string_)
    {
        sliceAssignArrayLiteralFromString(dest.isArrayLiteralExp(), src.isStringExp(), 0);
        return;
    }
    else if (src.op == EXP.arrayLiteral && dest.op == EXP.string_)
    {
        sliceAssignStringFromArrayLiteral(dest.isStringExp(), src.isArrayLiteralExp(), 0);
        return;
    }
    else
    {
        printf("invalid op %d %d\n", src.op, dest.op);
        assert(0);
    }
    assert(oldelems.dim == newelems.dim);
    foreach (size_t i; 0 .. oldelems.dim)
    {
        Expression e = (*newelems)[i];
        Expression o = (*oldelems)[i];
        if (e.op == EXP.structLiteral)
        {
            assert(o.op == e.op);
            assignInPlace(o, e);
        }
        else if (e.type.ty == Tsarray && e.op != EXP.void_ && o.type.ty == Tsarray)
        {
            assignInPlace(o, e);
        }
        else
        {
            (*oldelems)[i] = (*newelems)[i];
        }
    }
}

// Given an AA literal aae,  set aae[index] = newval and return newval.
Expression assignAssocArrayElement(const ref Loc loc, AssocArrayLiteralExp aae, Expression index, Expression newval)
{
    /* Create new associative array literal reflecting updated key/value
     */
    Expressions* keysx = aae.keys;
    Expressions* valuesx = aae.values;
    int updated = 0;
    for (size_t j = valuesx.dim; j;)
    {
        j--;
        Expression ekey = (*aae.keys)[j];
        int eq = ctfeEqual(loc, EXP.equal, ekey, index);
        if (eq)
        {
            (*valuesx)[j] = newval;
            updated = 1;
        }
    }
    if (!updated)
    {
        // Append index/newval to keysx[]/valuesx[]
        valuesx.push(newval);
        keysx.push(index);
    }
    return newval;
}

/// Given array literal oldval of type ArrayLiteralExp or StringExp, of length
/// oldlen, change its length to newlen. If the newlen is longer than oldlen,
/// all new elements will be set to the default initializer for the element type.
Expression changeArrayLiteralLength(UnionExp* pue, const ref Loc loc, TypeArray arrayType, Expression oldval, size_t oldlen, size_t newlen)
{
    Type elemType = arrayType.next;
    assert(elemType);
    Expression defaultElem = elemType.defaultInitLiteral(loc);
    auto elements = new Expressions(newlen);
    // Resolve slices
    size_t indxlo = 0;
    if (oldval.op == EXP.slice)
    {
        indxlo = cast(size_t)oldval.isSliceExp().lwr.toInteger();
        oldval = oldval.isSliceExp().e1;
    }
    size_t copylen = oldlen < newlen ? oldlen : newlen;
    if (oldval.op == EXP.string_)
    {
        StringExp oldse = oldval.isStringExp();
        void* s = mem.xcalloc(newlen + 1, oldse.sz);
        const data = oldse.peekData();
        memcpy(s, data.ptr, copylen * oldse.sz);
        const defaultValue = cast(uint)defaultElem.toInteger();
        foreach (size_t elemi; copylen .. newlen)
        {
            switch (oldse.sz)
            {
            case 1:
                (cast(char*)s)[cast(size_t)(indxlo + elemi)] = cast(char)defaultValue;
                break;
            case 2:
                (cast(wchar*)s)[cast(size_t)(indxlo + elemi)] = cast(wchar)defaultValue;
                break;
            case 4:
                (cast(dchar*)s)[cast(size_t)(indxlo + elemi)] = cast(dchar)defaultValue;
                break;
            default:
                assert(0);
            }
        }
        emplaceExp!(StringExp)(pue, loc, s[0 .. newlen * oldse.sz], newlen, oldse.sz);
        StringExp se = pue.exp().isStringExp();
        se.type = arrayType;
        se.sz = oldse.sz;
        se.committed = oldse.committed;
        se.ownedByCtfe = OwnedBy.ctfe;
    }
    else
    {
        if (oldlen != 0)
        {
            assert(oldval.op == EXP.arrayLiteral);
            ArrayLiteralExp ae = oldval.isArrayLiteralExp();
            foreach (size_t i; 0 .. copylen)
                (*elements)[i] = (*ae.elements)[indxlo + i];
        }
        if (elemType.ty == Tstruct || elemType.ty == Tsarray)
        {
            /* If it is an aggregate literal representing a value type,
             * we need to create a unique copy for each element
             */
            foreach (size_t i; copylen .. newlen)
                (*elements)[i] = copyLiteral(defaultElem).copy();
        }
        else
        {
            foreach (size_t i; copylen .. newlen)
                (*elements)[i] = defaultElem;
        }
        emplaceExp!(ArrayLiteralExp)(pue, loc, arrayType, elements);
        ArrayLiteralExp aae = pue.exp().isArrayLiteralExp();
        aae.ownedByCtfe = OwnedBy.ctfe;
    }
    return pue.exp();
}

/*************************** CTFE Sanity Checks ***************************/

bool isCtfeValueValid(Expression newval)
{
    Type tb = newval.type.toBasetype();
    switch (newval.op)
    {
        case EXP.int64:
        case EXP.float64:
        case EXP.char_:
        case EXP.complex80:
            return tb.isscalar();

        case EXP.null_:
            return tb.ty == Tnull    ||
                   tb.ty == Tpointer ||
                   tb.ty == Tarray   ||
                   tb.ty == Taarray  ||
                   tb.ty == Tclass   ||
                   tb.ty == Tdelegate;

        case EXP.string_:
            return true; // CTFE would directly use the StringExp in AST.

        case EXP.arrayLiteral:
            return true; //((ArrayLiteralExp *)newval)->ownedByCtfe;

        case EXP.assocArrayLiteral:
            return true; //((AssocArrayLiteralExp *)newval)->ownedByCtfe;

        case EXP.structLiteral:
            return true; //((StructLiteralExp *)newval)->ownedByCtfe;

        case EXP.classReference:
            return true;

        case EXP.type:
            return true;

        case EXP.vector:
            return true; // vector literal

        case EXP.function_:
            return true; // function literal or delegate literal

        case EXP.delegate_:
        {
            // &struct.func or &clasinst.func
            // &nestedfunc
            Expression ethis = newval.isDelegateExp().e1;
            return (ethis.op == EXP.structLiteral || ethis.op == EXP.classReference || ethis.op == EXP.variable && ethis.isVarExp().var == newval.isDelegateExp().func);
        }

        case EXP.symbolOffset:
        {
            // function pointer, or pointer to static variable
            Declaration d = newval.isSymOffExp().var;
            return d.isFuncDeclaration() || d.isDataseg();
        }

        case EXP.typeid_:
        {
            // always valid
            return true;
        }

        case EXP.address:
        {
            // e1 should be a CTFE reference
            Expression e1 = newval.isAddrExp().e1;
            return tb.ty == Tpointer &&
            (
                (e1.op == EXP.structLiteral || e1.op == EXP.arrayLiteral) && isCtfeValueValid(e1) ||
                 e1.op == EXP.variable ||
                 e1.op == EXP.dotVariable && isCtfeReferenceValid(e1) ||
                 e1.op == EXP.index && isCtfeReferenceValid(e1) ||
                 e1.op == EXP.slice && e1.type.toBasetype().ty == Tsarray
            );
        }

        case EXP.slice:
        {
            // e1 should be an array aggregate
            const SliceExp se = newval.isSliceExp();
            assert(se.lwr && se.lwr.op == EXP.int64);
            assert(se.upr && se.upr.op == EXP.int64);
            return (tb.ty == Tarray || tb.ty == Tsarray) && (se.e1.op == EXP.string_ || se.e1.op == EXP.arrayLiteral);
        }

        case EXP.void_:
            return true; // uninitialized value

        default:
            newval.error("CTFE internal error: illegal CTFE value `%s`", newval.toChars());
            return false;
    }
}

bool isCtfeReferenceValid(Expression newval)
{
    switch (newval.op)
    {
        case EXP.this_:
            return true;

        case EXP.variable:
        {
            const VarDeclaration v = newval.isVarExp().var.isVarDeclaration();
            assert(v);
            // Must not be a reference to a reference
            return true;
        }

        case EXP.index:
        {
            const Expression eagg = newval.isIndexExp().e1;
            return eagg.op == EXP.string_ || eagg.op == EXP.arrayLiteral || eagg.op == EXP.assocArrayLiteral;
        }

        case EXP.dotVariable:
        {
            Expression eagg = newval.isDotVarExp().e1;
            return (eagg.op == EXP.structLiteral || eagg.op == EXP.classReference) && isCtfeValueValid(eagg);
        }

        default:
            // Internally a ref variable may directly point a stack memory.
            // e.g. ref int v = 1;
            return isCtfeValueValid(newval);
    }
}

// Used for debugging only
void showCtfeExpr(Expression e, int level = 0)
{
    for (int i = level; i > 0; --i)
        printf(" ");
    Expressions* elements = null;
    // We need the struct definition to detect block assignment
    StructDeclaration sd = null;
    ClassDeclaration cd = null;
    if (e.op == EXP.structLiteral)
    {
        elements = e.isStructLiteralExp().elements;
        sd = e.isStructLiteralExp().sd;
        printf("STRUCT type = %s %p:\n", e.type.toChars(), e);
    }
    else if (e.op == EXP.classReference)
    {
        elements = e.isClassReferenceExp().value.elements;
        cd = e.isClassReferenceExp().originalClass();
        printf("CLASS type = %s %p:\n", e.type.toChars(), e.isClassReferenceExp().value);
    }
    else if (e.op == EXP.arrayLiteral)
    {
        elements = e.isArrayLiteralExp().elements;
        printf("ARRAY LITERAL type=%s %p:\n", e.type.toChars(), e);
    }
    else if (e.op == EXP.assocArrayLiteral)
    {
        printf("AA LITERAL type=%s %p:\n", e.type.toChars(), e);
    }
    else if (e.op == EXP.string_)
    {
        printf("STRING %s %p\n", e.toChars(), e.isStringExp.peekString.ptr);
    }
    else if (e.op == EXP.slice)
    {
        printf("SLICE %p: %s\n", e, e.toChars());
        showCtfeExpr(e.isSliceExp().e1, level + 1);
    }
    else if (e.op == EXP.variable)
    {
        printf("VAR %p %s\n", e, e.toChars());
        VarDeclaration v = e.isVarExp().var.isVarDeclaration();
        if (v && getValue(v))
            showCtfeExpr(getValue(v), level + 1);
    }
    else if (e.op == EXP.address)
    {
        // This is potentially recursive. We mustn't try to print the thing we're pointing to.
        printf("POINTER %p to %p: %s\n", e, e.isAddrExp().e1, e.toChars());
    }
    else
        printf("VALUE %p: %s\n", e, e.toChars());
    if (elements)
    {
        size_t fieldsSoFar = 0;
        for (size_t i = 0; i < elements.dim; i++)
        {
            Expression z = null;
            VarDeclaration v = null;
            if (i > 15)
            {
                printf("...(total %d elements)\n", cast(int)elements.dim);
                return;
            }
            if (sd)
            {
                v = sd.fields[i];
                z = (*elements)[i];
            }
            else if (cd)
            {
                while (i - fieldsSoFar >= cd.fields.dim)
                {
                    fieldsSoFar += cd.fields.dim;
                    cd = cd.baseClass;
                    for (int j = level; j > 0; --j)
                        printf(" ");
                    printf(" BASE CLASS: %s\n", cd.toChars());
                }
                v = cd.fields[i - fieldsSoFar];
                assert((elements.dim + i) >= (fieldsSoFar + cd.fields.dim));
                size_t indx = (elements.dim - fieldsSoFar) - cd.fields.dim + i;
                assert(indx < elements.dim);
                z = (*elements)[indx];
            }
            if (!z)
            {
                for (int j = level; j > 0; --j)
                    printf(" ");
                printf(" void\n");
                continue;
            }
            if (v)
            {
                // If it is a void assignment, use the default initializer
                if ((v.type.ty != z.type.ty) && v.type.ty == Tsarray)
                {
                    for (int j = level; --j;)
                        printf(" ");
                    printf(" field: block initialized static array\n");
                    continue;
                }
            }
            showCtfeExpr(z, level + 1);
        }
    }
}

/*************************** Void initialization ***************************/
UnionExp voidInitLiteral(Type t, VarDeclaration var)
{
    UnionExp ue;
    if (t.ty == Tsarray)
    {
        TypeSArray tsa = cast(TypeSArray)t;
        Expression elem = voidInitLiteral(tsa.next, var).copy();
        // For aggregate value types (structs, static arrays) we must
        // create an a separate copy for each element.
        const mustCopy = (elem.op == EXP.arrayLiteral || elem.op == EXP.structLiteral);
        const d = cast(size_t)tsa.dim.toInteger();
        auto elements = new Expressions(d);
        foreach (i; 0 .. d)
        {
            if (mustCopy && i > 0)
                elem = copyLiteral(elem).copy();
            (*elements)[i] = elem;
        }
        emplaceExp!(ArrayLiteralExp)(&ue, var.loc, tsa, elements);
        ArrayLiteralExp ae = ue.exp().isArrayLiteralExp();
        ae.ownedByCtfe = OwnedBy.ctfe;
    }
    else if (t.ty == Tstruct)
    {
        TypeStruct ts = cast(TypeStruct)t;
        auto exps = new Expressions(ts.sym.fields.dim);
        foreach (size_t i;  0 .. ts.sym.fields.dim)
        {
            (*exps)[i] = voidInitLiteral(ts.sym.fields[i].type, ts.sym.fields[i]).copy();
        }
        emplaceExp!(StructLiteralExp)(&ue, var.loc, ts.sym, exps);
        StructLiteralExp se = ue.exp().isStructLiteralExp();
        se.type = ts;
        se.ownedByCtfe = OwnedBy.ctfe;
    }
    else
        emplaceExp!(VoidInitExp)(&ue, var);
    return ue;
}
