
/* 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/escape.c
 */

#include "mars.h"
#include "init.h"
#include "expression.h"
#include "scope.h"
#include "aggregate.h"
#include "declaration.h"
#include "module.h"

/************************************
 * Aggregate the data collected by the escapeBy??() functions.
 */
struct EscapeByResults
{
    VarDeclarations byref;      // array into which variables being returned by ref are inserted
    VarDeclarations byvalue;    // array into which variables with values containing pointers are inserted
    FuncDeclarations byfunc;    // nested functions that are turned into delegates
    Expressions byexp;          // array into which temporaries being returned by ref are inserted
};

static bool checkReturnEscapeImpl(Scope *sc, Expression *e, bool refs, bool gag);
static void inferReturn(FuncDeclaration *fd, VarDeclaration *v);
static void escapeByValue(Expression *e, EscapeByResults *er);
static void escapeByRef(Expression *e, EscapeByResults *er);
static void findAllOuterAccessedVariables(FuncDeclaration *fd, VarDeclarations *vars);

/* 'v' is assigned unsafely to 'par'
*/
static void unsafeAssign(Scope *sc, FuncDeclaration *fdc, Identifier *par, Expression *arg, bool gag,
                         bool &result, VarDeclaration *v, const char *desc)
{
    if (global.params.vsafe && sc->func->setUnsafe())
    {
        if (!gag)
            error(arg->loc, "%s %s assigned to non-scope parameter %s calling %s",
                desc, v->toChars(),
                par ? par->toChars() : "unnamed",
                fdc ? fdc->toPrettyChars() : "indirectly");
        result = true;
    }
}

/****************************************
 * Function parameter par is being initialized to arg,
 * and par may escape.
 * Detect if scoped values can escape this way.
 * Print error messages when these are detected.
 * Params:
 *      sc = used to determine current function and module
 *      par = identifier of function parameter
 *      arg = initializer for param
 *      gag = do not print error messages
 * Returns:
 *      true if pointers to the stack can escape via assignment
 */
bool checkParamArgumentEscape(Scope *sc, FuncDeclaration *fdc, Identifier *par, Expression *arg, bool gag)
{
    //printf("checkParamArgumentEscape(arg: %s par: %s)\n", arg->toChars(), par->toChars());
    //printf("type = %s, %d\n", arg->type->toChars(), arg->type->hasPointers());

    if (!arg->type->hasPointers())
        return false;

    EscapeByResults er;

    escapeByValue(arg, &er);

    if (!er.byref.length && !er.byvalue.length && !er.byfunc.length && !er.byexp.length)
        return false;

    bool result = false;

    for (size_t i = 0; i < er.byvalue.length; i++)
    {
        //printf("byvalue %s\n", v->toChars());
        VarDeclaration *v = er.byvalue[i];
        if (v->isDataseg())
            continue;

        Dsymbol *p = v->toParent2();

        v->storage_class &= ~STCmaybescope;

        if (v->isScope())
        {
            unsafeAssign(sc, fdc, par, arg, gag, result, v, "scope variable");
        }
        else if (v->storage_class & STCvariadic && p == sc->func)
        {
            Type *tb = v->type->toBasetype();
            if (tb->ty == Tarray || tb->ty == Tsarray)
            {
                unsafeAssign(sc, fdc, par, arg, gag, result, v, "variadic variable");
            }
        }
        else
        {
            /* v is not 'scope', and is assigned to a parameter that may escape.
             * Therefore, v can never be 'scope'.
             */
            v->doNotInferScope = true;
        }
    }

    for (size_t i = 0; i < er.byref.length; i++)
    {
        VarDeclaration *v = er.byref[i];
        if (v->isDataseg())
            continue;

        Dsymbol *p = v->toParent2();

        v->storage_class &= ~STCmaybescope;

        if ((v->storage_class & (STCref | STCout)) == 0 && p == sc->func)
        {
            unsafeAssign(sc, fdc, par, arg, gag, result, v, "reference to local variable");
            continue;
        }
    }

    for (size_t i = 0; i < er.byfunc.length; i++)
    {
        FuncDeclaration *fd = er.byfunc[i];
        //printf("fd = %s, %d\n", fd->toChars(), fd->tookAddressOf);
        VarDeclarations vars;
        findAllOuterAccessedVariables(fd, &vars);

        for (size_t j = 0; j < vars.length; j++)
        {
            VarDeclaration *v = vars[j];
            //printf("v = %s\n", v->toChars());
            assert(!v->isDataseg());     // these are not put in the closureVars[]

            Dsymbol *p = v->toParent2();

            v->storage_class &= ~STCmaybescope;

            if ((v->storage_class & (STCref | STCout | STCscope)) && p == sc->func)
            {
                unsafeAssign(sc, fdc, par, arg, gag, result, v, "reference to local");
                continue;
            }
        }
    }

    for (size_t i = 0; i < er.byexp.length; i++)
    {
        Expression *ee = er.byexp[i];
        if (sc->func->setUnsafe())
        {
            if (!gag)
                error(ee->loc, "reference to stack allocated value returned by %s assigned to non-scope parameter %s",
                    ee->toChars(),
                    par ? par->toChars() : "unnamed");
            result = true;
        }
    }

    return result;
}

/****************************************
 * Given an AssignExp, determine if the lvalue will cause
 * the contents of the rvalue to escape.
 * Print error messages when these are detected.
 * Infer 'scope' for the lvalue where possible, in order
 * to eliminate the error.
 * Params:
 *      sc = used to determine current function and module
 *      ae = AssignExp to check for any pointers to the stack
 *      gag = do not print error messages
 * Returns:
 *      true if pointers to the stack can escape via assignment
 */
bool checkAssignEscape(Scope *sc, Expression *e, bool gag)
{
    //printf("checkAssignEscape(e: %s)\n", e->toChars());
    if (e->op != TOKassign && e->op != TOKblit && e->op != TOKconstruct)
        return false;
    AssignExp *ae = (AssignExp *)e;
    Expression *e1 = ae->e1;
    Expression *e2 = ae->e2;
    //printf("type = %s, %d\n", e1->type->toChars(), e1->type->hasPointers());

    if (!e1->type->hasPointers())
        return false;

    if (e1->op == TOKslice)
        return false;

    EscapeByResults er;

    escapeByValue(e2, &er);

    if (!er.byref.length && !er.byvalue.length && !er.byfunc.length && !er.byexp.length)
        return false;

    VarDeclaration *va = NULL;
    while (e1->op == TOKdotvar)
        e1 = ((DotVarExp *)e1)->e1;

    if (e1->op == TOKvar)
        va = ((VarExp *)e1)->var->isVarDeclaration();
    else if (e1->op == TOKthis)
        va = ((ThisExp *)e1)->var->isVarDeclaration();
    else if (e1->op == TOKindex)
    {
        IndexExp *ie = (IndexExp *)e1;
        if (ie->e1->op == TOKvar && ie->e1->type->toBasetype()->ty == Tsarray)
            va = ((VarExp *)ie->e1)->var->isVarDeclaration();
    }

    // Try to infer 'scope' for va if in a function not marked @system
    bool inferScope = false;
    if (va && sc->func && sc->func->type && sc->func->type->ty == Tfunction)
        inferScope = ((TypeFunction *)sc->func->type)->trust != TRUSTsystem;

    bool result = false;
    for (size_t i = 0; i < er.byvalue.length; i++)
    {
        VarDeclaration *v = er.byvalue[i];
        //printf("byvalue: %s\n", v->toChars());
        if (v->isDataseg())
            continue;

        Dsymbol *p = v->toParent2();

        if (!(va && va->isScope()))
            v->storage_class &= ~STCmaybescope;

        if (v->isScope())
        {
            if (va && va->isScope() && va->storage_class & STCreturn && !(v->storage_class & STCreturn) &&
                sc->func->setUnsafe())
            {
                if (!gag)
                    error(ae->loc, "scope variable %s assigned to return scope %s", v->toChars(), va->toChars());
                result = true;
                continue;
            }

            // If va's lifetime encloses v's, then error
            if (va &&
                ((va->enclosesLifetimeOf(v) && !(v->storage_class & STCparameter)) ||
                 // va is class reference
                 (ae->e1->op == TOKdotvar && va->type->toBasetype()->ty == Tclass && (va->enclosesLifetimeOf(v) || !va->isScope())) ||
                 va->storage_class & STCref) &&
                sc->func->setUnsafe())
            {
                if (!gag)
                    error(ae->loc, "scope variable %s assigned to %s with longer lifetime", v->toChars(), va->toChars());
                result = true;
                continue;
            }

            if (va && !va->isDataseg() && !va->doNotInferScope)
            {
                if (!va->isScope() && inferScope)
                {   //printf("inferring scope for %s\n", va->toChars());
                    va->storage_class |= STCscope | STCscopeinferred;
                    va->storage_class |= v->storage_class & STCreturn;
                }
                continue;
            }
            if (sc->func->setUnsafe())
            {
                if (!gag)
                    error(ae->loc, "scope variable %s assigned to non-scope %s", v->toChars(), e1->toChars());
                result = true;
            }
        }
        else if (v->storage_class & STCvariadic && p == sc->func)
        {
            Type *tb = v->type->toBasetype();
            if (tb->ty == Tarray || tb->ty == Tsarray)
            {
                if (va && !va->isDataseg() && !va->doNotInferScope)
                {
                    if (!va->isScope() && inferScope)
                    {   //printf("inferring scope for %s\n", va->toChars());
                        va->storage_class |= STCscope | STCscopeinferred;
                    }
                    continue;
                }
                if (sc->func->setUnsafe())
                {
                    if (!gag)
                        error(ae->loc, "variadic variable %s assigned to non-scope %s", v->toChars(), e1->toChars());
                    result = true;
                }
            }
        }
        else
        {
            /* v is not 'scope', and we didn't check the scope of where we assigned it to.
             * It may escape via that assignment, therefore, v can never be 'scope'.
             */
            v->doNotInferScope = true;
        }
    }

    for (size_t i = 0; i < er.byref.length; i++)
    {
        VarDeclaration *v = er.byref[i];
        //printf("byref: %s\n", v->toChars());
        if (v->isDataseg())
            continue;

        Dsymbol *p = v->toParent2();

        // If va's lifetime encloses v's, then error
        if (va &&
            ((va->enclosesLifetimeOf(v) && !(v->storage_class & STCparameter)) || va->storage_class & STCref) &&
            sc->func->setUnsafe())
        {
            if (!gag)
                error(ae->loc, "address of variable %s assigned to %s with longer lifetime", v->toChars(), va->toChars());
            result = true;
            continue;
        }

        if (!(va && va->isScope()))
            v->storage_class &= ~STCmaybescope;

        if ((v->storage_class & (STCref | STCout)) == 0 && p == sc->func)
        {
            if (va && !va->isDataseg() && !va->doNotInferScope)
            {
                if (!va->isScope() && inferScope)
                {   //printf("inferring scope for %s\n", va->toChars());
                    va->storage_class |= STCscope | STCscopeinferred;
                }
                continue;
            }
            if (sc->func->setUnsafe())
            {
                if (!gag)
                    error(ae->loc, "reference to local variable %s assigned to non-scope %s", v->toChars(), e1->toChars());
                result = true;
            }
            continue;
        }
    }

    for (size_t i = 0; i < er.byfunc.length; i++)
    {
        FuncDeclaration *fd = er.byfunc[i];
        //printf("fd = %s, %d\n", fd->toChars(), fd->tookAddressOf);
        VarDeclarations vars;
        findAllOuterAccessedVariables(fd, &vars);

        for (size_t j = 0; j < vars.length; j++)
        {
            VarDeclaration *v = vars[j];
            //printf("v = %s\n", v->toChars());
            assert(!v->isDataseg());     // these are not put in the closureVars[]

            Dsymbol *p = v->toParent2();

            if (!(va && va->isScope()))
                v->storage_class &= ~STCmaybescope;

            if ((v->storage_class & (STCref | STCout | STCscope)) && p == sc->func)
            {
                if (va && !va->isDataseg() && !va->doNotInferScope)
                {
                    /* Don't infer STCscope for va, because then a closure
                     * won't be generated for sc->func.
                     */
                    //if (!va->isScope() && inferScope)
                        //va->storage_class |= STCscope | STCscopeinferred;
                    continue;
                }
                if (sc->func->setUnsafe())
                {
                    if (!gag)
                        error(ae->loc, "reference to local %s assigned to non-scope %s in @safe code", v->toChars(), e1->toChars());
                    result = true;
                }
                continue;
            }
        }
    }

    for (size_t i = 0; i < er.byexp.length; i++)
    {
        Expression *ee = er.byexp[i];
        if (va && !va->isDataseg() && !va->doNotInferScope)
        {
            if (!va->isScope() && inferScope)
            {   //printf("inferring scope for %s\n", va->toChars());
                va->storage_class |= STCscope | STCscopeinferred;
            }
            continue;
        }
        if (sc->func->setUnsafe())
        {
            if (!gag)
                error(ee->loc, "reference to stack allocated value returned by %s assigned to non-scope %s",
                    ee->toChars(), e1->toChars());
            result = true;
        }
    }

    return result;
}

/************************************
 * Detect cases where pointers to the stack can 'escape' the
 * lifetime of the stack frame when throwing `e`.
 * Print error messages when these are detected.
 * Params:
 *      sc = used to determine current function and module
 *      e = expression to check for any pointers to the stack
 *      gag = do not print error messages
 * Returns:
 *      true if pointers to the stack can escape
 */
bool checkThrowEscape(Scope *sc, Expression *e, bool gag)
{
    //printf("[%s] checkThrowEscape, e = %s\n", e->loc->toChars(), e->toChars());
    EscapeByResults er;

    escapeByValue(e, &er);

    if (!er.byref.length && !er.byvalue.length && !er.byexp.length)
        return false;

    bool result = false;
    for (size_t i = 0; i < er.byvalue.length; i++)
    {
        VarDeclaration *v = er.byvalue[i];
        //printf("byvalue %s\n", v->toChars());
        if (v->isDataseg())
            continue;

        if (v->isScope())
        {
            if (sc->_module && sc->_module->isRoot())
            {
                // Only look for errors if in module listed on command line
                if (global.params.vsafe) // https://issues.dlang.org/show_bug.cgi?id=17029
                {
                    if (!gag)
                        error(e->loc, "scope variable %s may not be thrown", v->toChars());
                    result = true;
                }
                continue;
            }
        }
        else
        {
            //printf("no infer for %s\n", v->toChars());
            v->doNotInferScope = true;
        }
    }
    return result;
}

/************************************
 * Detect cases where pointers to the stack can 'escape' the
 * lifetime of the stack frame by returning 'e' by value.
 * Params:
 *      sc = used to determine current function and module
 *      e = expression to check for any pointers to the stack
 *      gag = do not print error messages
 * Returns:
 *      true if pointers to the stack can escape
 */

bool checkReturnEscape(Scope *sc, Expression *e, bool gag)
{
    //printf("[%s] checkReturnEscape, e = %s\n", e->loc->toChars(), e->toChars());
    return checkReturnEscapeImpl(sc, e, false, gag);
}

/************************************
 * Detect cases where returning 'e' by ref can result in a reference to the stack
 * being returned.
 * Print error messages when these are detected.
 * Params:
 *      sc = used to determine current function and module
 *      e = expression to check
 *      gag = do not print error messages
 * Returns:
 *      true if references to the stack can escape
 */
bool checkReturnEscapeRef(Scope *sc, Expression *e, bool gag)
{
    //printf("[%s] checkReturnEscapeRef, e = %s\n", e->loc.toChars(), e->toChars());
    //printf("current function %s\n", sc->func->toChars());
    //printf("parent2 function %s\n", sc->func->toParent2()->toChars());

    return checkReturnEscapeImpl(sc, e, true, gag);
}

static void escapingRef(VarDeclaration *v, Expression *e, bool &result, bool gag)
{
    if (!gag)
    {
        const char *msg;
        if (v->storage_class & STCparameter)
            msg = "returning `%s` escapes a reference to parameter `%s`, perhaps annotate with `return`";
        else
            msg = "returning `%s` escapes a reference to local variable `%s`";
        error(e->loc, msg, e->toChars(), v->toChars());
    }
    result = true;
}

static bool checkReturnEscapeImpl(Scope *sc, Expression *e, bool refs, bool gag)
{
    //printf("[%s] checkReturnEscapeImpl, e = %s\n", e->loc->toChars(), e->toChars());
    EscapeByResults er;

    if (refs)
        escapeByRef(e, &er);
    else
        escapeByValue(e, &er);

    if (!er.byref.length && !er.byvalue.length && !er.byexp.length)
        return false;

    bool result = false;
    for (size_t i = 0; i < er.byvalue.length; i++)
    {
        VarDeclaration *v = er.byvalue[i];
        //printf("byvalue %s\n", v->toChars());
        if (v->isDataseg())
            continue;

        Dsymbol *p = v->toParent2();

        if ((v->isScope() || (v->storage_class & STCmaybescope)) &&
            !(v->storage_class & STCreturn) &&
            v->isParameter() &&
            sc->func->flags & FUNCFLAGreturnInprocess &&
            p == sc->func)
        {
            inferReturn(sc->func, v);        // infer addition of 'return'
            continue;
        }

        if (v->isScope())
        {
            if (v->storage_class & STCreturn)
                continue;

            if (sc->_module && sc->_module->isRoot() &&
                /* This case comes up when the ReturnStatement of a __foreachbody is
                 * checked for escapes by the caller of __foreachbody. Skip it.
                 *
                 * struct S { static int opApply(int delegate(S*) dg); }
                 * S* foo() {
                 *    foreach (S* s; S) // create __foreachbody for body of foreach
                 *        return s;     // s is inferred as 'scope' but incorrectly tested in foo()
                 *    return null; }
                 */
                !(!refs && p->parent == sc->func))
            {
                // Only look for errors if in module listed on command line
                if (global.params.vsafe) // https://issues.dlang.org/show_bug.cgi?id=17029
                {
                    if (!gag)
                        error(e->loc, "scope variable %s may not be returned", v->toChars());
                    result = true;
                }
                continue;
            }
        }
        else if (v->storage_class & STCvariadic && p == sc->func)
        {
            Type *tb = v->type->toBasetype();
            if (tb->ty == Tarray || tb->ty == Tsarray)
            {
                if (!gag)
                    error(e->loc, "returning `%s` escapes a reference to variadic parameter `%s`", e->toChars(), v->toChars());
                result = false;
            }
        }
        else
        {
            //printf("no infer for %s\n", v->toChars());
            v->doNotInferScope = true;
        }
    }

    for (size_t i = 0; i < er.byref.length; i++)
    {
        VarDeclaration *v = er.byref[i];
        //printf("byref %s\n", v->toChars());
        if (v->isDataseg())
            continue;

        Dsymbol *p = v->toParent2();

        if ((v->storage_class & (STCref | STCout)) == 0)
        {
            if (p == sc->func)
            {
                escapingRef(v, e, result, gag);
                continue;
            }
            FuncDeclaration *fd = p->isFuncDeclaration();
            if (fd && sc->func->flags & FUNCFLAGreturnInprocess)
            {
                /* Code like:
                 *   int x;
                 *   auto dg = () { return &x; }
                 * Making it:
                 *   auto dg = () return { return &x; }
                 * Because dg.ptr points to x, this is returning dt.ptr+offset
                 */
                if (global.params.vsafe)
                    sc->func->storage_class |= STCreturn;
            }
        }

        /* Check for returning a ref variable by 'ref', but should be 'return ref'
         * Infer the addition of 'return', or set result to be the offending expression.
         */
        if ( (v->storage_class & (STCref | STCout)) &&
             !(v->storage_class & (STCreturn | STCforeach)))
        {
            if ((sc->func->flags & FUNCFLAGreturnInprocess) && p == sc->func)
            {
                inferReturn(sc->func, v);        // infer addition of 'return'
            }
            else if (global.params.useDIP25 &&
                     sc->_module && sc->_module->isRoot())
            {
                // Only look for errors if in module listed on command line

                if (p == sc->func)
                {
                    //printf("escaping reference to local ref variable %s\n", v->toChars());
                    //printf("storage class = x%llx\n", v->storage_class);
                    escapingRef(v, e, result, gag);
                    continue;
                }
                // Don't need to be concerned if v's parent does not return a ref
                FuncDeclaration *fd = p->isFuncDeclaration();
                if (fd && fd->type && fd->type->ty == Tfunction)
                {
                    TypeFunction *tf = (TypeFunction *)fd->type;
                    if (tf->isref)
                    {
                        if (!gag)
                            error(e->loc, "escaping reference to outer local variable %s", v->toChars());
                        result = true;
                        continue;
                    }
                }
            }
        }
    }

    for (size_t i = 0; i < er.byexp.length; i++)
    {
        Expression *ee = er.byexp[i];
        //printf("byexp %s\n", ee->toChars());
        if (!gag)
            error(ee->loc, "escaping reference to stack allocated value returned by %s", ee->toChars());
        result = true;
    }

    return result;
}


/*************************************
 * Variable v needs to have 'return' inferred for it.
 * Params:
 *      fd = function that v is a parameter to
 *      v = parameter that needs to be STCreturn
 */

static void inferReturn(FuncDeclaration *fd, VarDeclaration *v)
{
    // v is a local in the current function

    //printf("for function '%s' inferring 'return' for variable '%s'\n", fd->toChars(), v->toChars());
    v->storage_class |= STCreturn;

    TypeFunction *tf = (TypeFunction *)fd->type;
    if (v == fd->vthis)
    {
        /* v is the 'this' reference, so mark the function
         */
        fd->storage_class |= STCreturn;
        if (tf->ty == Tfunction)
        {
            //printf("'this' too %p %s\n", tf, sc->func->toChars());
            tf->isreturn = true;
        }
    }
    else
    {
        // Perform 'return' inference on parameter
        if (tf->ty == Tfunction)
        {
            const size_t dim = tf->parameterList.length();
            for (size_t i = 0; i < dim; i++)
            {
                Parameter *p = tf->parameterList[i];
                if (p->ident == v->ident)
                {
                    p->storageClass |= STCreturn;
                    break;              // there can be only one
                }
            }
        }
    }
}


/****************************************
 * e is an expression to be returned by value, and that value contains pointers.
 * Walk e to determine which variables are possibly being
 * returned by value, such as:
 *      int* function(int* p) { return p; }
 * If e is a form of &p, determine which variables have content
 * which is being returned as ref, such as:
 *      int* function(int i) { return &i; }
 * Multiple variables can be inserted, because of expressions like this:
 *      int function(bool b, int i, int* p) { return b ? &i : p; }
 *
 * No side effects.
 *
 * Params:
 *      e = expression to be returned by value
 *      er = where to place collected data
 */
static void escapeByValue(Expression *e, EscapeByResults *er)
{
    //printf("[%s] escapeByValue, e: %s\n", e->loc.toChars(), e->toChars());

    class EscapeVisitor : public Visitor
    {
    public:
        EscapeByResults *er;

        EscapeVisitor(EscapeByResults *er)
            : er(er)
        {
        }

        void visit(Expression *)
        {
        }

        void visit(AddrExp *e)
        {
            escapeByRef(e->e1, er);
        }

        void visit(SymOffExp *e)
        {
            VarDeclaration *v = e->var->isVarDeclaration();
            if (v)
                er->byref.push(v);
        }

        void visit(VarExp *e)
        {
            VarDeclaration *v = e->var->isVarDeclaration();
            if (v)
                er->byvalue.push(v);
        }

        void visit(ThisExp *e)
        {
            if (e->var)
                er->byvalue.push(e->var);
        }

        void visit(DotVarExp *e)
        {
            Type *t = e->e1->type->toBasetype();
            if (t->ty == Tstruct)
                e->e1->accept(this);
        }

        void visit(DelegateExp *e)
        {
            Type *t = e->e1->type->toBasetype();
            if (t->ty == Tclass || t->ty == Tpointer)
                escapeByValue(e->e1, er);
            else
                escapeByRef(e->e1, er);
            er->byfunc.push(e->func);
        }

        void visit(FuncExp *e)
        {
            if (e->fd->tok == TOKdelegate)
                er->byfunc.push(e->fd);
        }

        void visit(TupleExp *)
        {
            assert(0); // should have been lowered by now
        }

        void visit(ArrayLiteralExp *e)
        {
            Type *tb = e->type->toBasetype();
            if (tb->ty == Tsarray || tb->ty == Tarray)
            {
                if (e->basis)
                    e->basis->accept(this);
                for (size_t i = 0; i < e->elements->length; i++)
                {
                    Expression *el = (*e->elements)[i];
                    if (el)
                        el->accept(this);
                }
            }
        }

        void visit(StructLiteralExp *e)
        {
            if (e->elements)
            {
                for (size_t i = 0; i < e->elements->length; i++)
                {
                    Expression *ex = (*e->elements)[i];
                    if (ex)
                        ex->accept(this);
                }
            }
        }

        void visit(NewExp *e)
        {
            Type *tb = e->newtype->toBasetype();
            if (tb->ty == Tstruct && !e->member && e->arguments)
            {
                for (size_t i = 0; i < e->arguments->length; i++)
                {
                    Expression *ex = (*e->arguments)[i];
                    if (ex)
                        ex->accept(this);
                }
            }
        }

        void visit(CastExp *e)
        {
            Type *tb = e->type->toBasetype();
            if (tb->ty == Tarray &&
                e->e1->type->toBasetype()->ty == Tsarray)
            {
                escapeByRef(e->e1, er);
            }
            else
                e->e1->accept(this);
        }

        void visit(SliceExp *e)
        {
            if (e->e1->op == TOKvar)
            {
                VarDeclaration *v = ((VarExp *)e->e1)->var->isVarDeclaration();
                Type *tb = e->type->toBasetype();
                if (v)
                {
                    if (tb->ty == Tsarray)
                        return;
                    if (v->storage_class & STCvariadic)
                    {
                        er->byvalue.push(v);
                        return;
                    }
                }
            }
            Type *t1b = e->e1->type->toBasetype();
            if (t1b->ty == Tsarray)
            {
                Type *tb = e->type->toBasetype();
                if (tb->ty != Tsarray)
                    escapeByRef(e->e1, er);
            }
            else
                e->e1->accept(this);
        }

        void visit(BinExp *e)
        {
            Type *tb = e->type->toBasetype();
            if (tb->ty == Tpointer)
            {
                e->e1->accept(this);
                e->e2->accept(this);
            }
        }

        void visit(BinAssignExp *e)
        {
            e->e1->accept(this);
        }

        void visit(AssignExp *e)
        {
            e->e1->accept(this);
        }

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

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

        void visit(CallExp *e)
        {
            //printf("CallExp(): %s\n", e->toChars());
            /* Check each argument that is
             * passed as 'return scope'.
             */
            Type *t1 = e->e1->type->toBasetype();
            TypeFunction *tf = NULL;
            TypeDelegate *dg = NULL;
            if (t1->ty == Tdelegate)
            {
                dg = (TypeDelegate *)t1;
                tf = (TypeFunction *)dg->next;
            }
            else if (t1->ty == Tfunction)
                tf = (TypeFunction *)t1;
            else
                return;

            if (e->arguments && e->arguments->length)
            {
                /* j=1 if _arguments[] is first argument,
                 * skip it because it is not passed by ref
                 */
                size_t j = tf->isDstyleVariadic();
                for (size_t i = j; i < e->arguments->length; ++i)
                {
                    Expression *arg = (*e->arguments)[i];
                    size_t nparams = tf->parameterList.length();
                    if (i - j < nparams && i >= j)
                    {
                        Parameter *p = tf->parameterList[i - j];
                        const StorageClass stc = tf->parameterStorageClass(p);
                        if ((stc & (STCscope)) && (stc & STCreturn))
                            arg->accept(this);
                        else if ((stc & (STCref)) && (stc & STCreturn))
                            escapeByRef(arg, er);
                    }
                }
            }
            // If 'this' is returned, check it too
            if (e->e1->op == TOKdotvar && t1->ty == Tfunction)
            {
                DotVarExp *dve = (DotVarExp *)e->e1;
                FuncDeclaration *fd = dve->var->isFuncDeclaration();
                AggregateDeclaration *ad = NULL;
                if (global.params.vsafe && tf->isreturn && fd && (ad = fd->isThis()) != NULL)
                {
                    if (ad->isClassDeclaration() || tf->isscope)       // this is 'return scope'
                        dve->e1->accept(this);
                    else if (ad->isStructDeclaration()) // this is 'return ref'
                        escapeByRef(dve->e1, er);
                }
                else if (dve->var->storage_class & STCreturn || tf->isreturn)
                {
                    if (dve->var->storage_class & STCscope)
                        dve->e1->accept(this);
                    else if (dve->var->storage_class & STCref)
                        escapeByRef(dve->e1, er);
                }
            }

            /* If returning the result of a delegate call, the .ptr
             * field of the delegate must be checked.
             */
            if (dg)
            {
                if (tf->isreturn)
                    e->e1->accept(this);
            }
        }
    };

    EscapeVisitor v(er);
    e->accept(&v);
}

/****************************************
 * e is an expression to be returned by 'ref'.
 * Walk e to determine which variables are possibly being
 * returned by ref, such as:
 *      ref int function(int i) { return i; }
 * If e is a form of *p, determine which variables have content
 * which is being returned as ref, such as:
 *      ref int function(int* p) { return *p; }
 * Multiple variables can be inserted, because of expressions like this:
 *      ref int function(bool b, int i, int* p) { return b ? i : *p; }
 *
 * No side effects.
 *
 * Params:
 *      e = expression to be returned by 'ref'
 *      er = where to place collected data
 */
static void escapeByRef(Expression *e, EscapeByResults *er)
{
    //printf("[%s] escapeByRef, e: %s\n", e->loc->toChars(), e->toChars());
    class EscapeRefVisitor : public Visitor
    {
    public:
        EscapeByResults *er;

        EscapeRefVisitor(EscapeByResults *er)
            : er(er)
        {
        }

        void visit(Expression *)
        {
        }

        void visit(VarExp *e)
        {
            VarDeclaration *v = e->var->isVarDeclaration();
            if (v)
            {
                if (v->storage_class & STCref && v->storage_class & (STCforeach | STCtemp) && v->_init)
                {
                    /* If compiler generated ref temporary
                     *   (ref v = ex; ex)
                     * look at the initializer instead
                     */
                    if (ExpInitializer *ez = v->_init->isExpInitializer())
                    {
                        assert(ez->exp && ez->exp->op == TOKconstruct);
                        Expression *ex = ((ConstructExp *)ez->exp)->e2;
                        ex->accept(this);
                    }
                }
                else
                    er->byref.push(v);
            }
        }

        void visit(ThisExp *e)
        {
            if (e->var)
                er->byref.push(e->var);
        }

        void visit(PtrExp *e)
        {
            escapeByValue(e->e1, er);
        }

        void visit(IndexExp *e)
        {
            Type *tb = e->e1->type->toBasetype();
            if (e->e1->op == TOKvar)
            {
                VarDeclaration *v = ((VarExp *)e->e1)->var->isVarDeclaration();
                if (tb->ty == Tarray || tb->ty == Tsarray)
                {
                    if (v->storage_class & STCvariadic)
                    {
                        er->byref.push(v);
                        return;
                    }
                }
            }
            if (tb->ty == Tsarray)
            {
                e->e1->accept(this);
            }
            else if (tb->ty == Tarray)
            {
                escapeByValue(e->e1, er);
            }
        }

        void visit(DotVarExp *e)
        {
            Type *t1b = e->e1->type->toBasetype();
            if (t1b->ty == Tclass)
                escapeByValue(e->e1, er);
            else
                e->e1->accept(this);
        }

        void visit(BinAssignExp *e)
        {
            e->e1->accept(this);
        }

        void visit(AssignExp *e)
        {
            e->e1->accept(this);
        }

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

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

        void visit(CallExp *e)
        {
            /* If the function returns by ref, check each argument that is
             * passed as 'return ref'.
             */
            Type *t1 = e->e1->type->toBasetype();
            TypeFunction *tf;
            if (t1->ty == Tdelegate)
                tf = (TypeFunction *)((TypeDelegate *)t1)->next;
            else if (t1->ty == Tfunction)
                tf = (TypeFunction *)t1;
            else
                return;
            if (tf->isref)
            {
                if (e->arguments && e->arguments->length)
                {
                    /* j=1 if _arguments[] is first argument,
                     * skip it because it is not passed by ref
                     */
                    size_t j = tf->isDstyleVariadic();

                    for (size_t i = j; i < e->arguments->length; ++i)
                    {
                        Expression *arg = (*e->arguments)[i];
                        size_t nparams = tf->parameterList.length();
                        if (i - j < nparams && i >= j)
                        {
                            Parameter *p = tf->parameterList[i - j];
                            const StorageClass stc = tf->parameterStorageClass(p);
                            if ((stc & (STCout | STCref)) && (stc & STCreturn))
                                arg->accept(this);
                            else if ((stc & STCscope) && (stc & STCreturn))
                            {
                                if (arg->op == TOKdelegate)
                                {
                                    DelegateExp *de = (DelegateExp *)arg;
                                    if (de->func->isNested())
                                        er->byexp.push(de);
                                }
                                else
                                    escapeByValue(arg, er);
                            }
                        }
                    }
                }

                // If 'this' is returned by ref, check it too
                if (e->e1->op == TOKdotvar && t1->ty == Tfunction)
                {
                    DotVarExp *dve = (DotVarExp *)e->e1;
                    if (dve->var->storage_class & STCreturn || tf->isreturn)
                    {
                        if ((dve->var->storage_class & STCscope) || tf->isscope)
                            escapeByValue(dve->e1, er);
                        else if ((dve->var->storage_class & STCref) || tf->isref)
                            dve->e1->accept(this);
                    }

                }
                // If it's a delegate, check it too
                if (e->e1->op == TOKvar && t1->ty == Tdelegate)
                {
                    escapeByValue(e->e1, er);
                }
            }
            else
                er->byexp.push(e);
        }
    };

    EscapeRefVisitor v(er);
    e->accept(&v);
}

/*************************
 * Find all variables accessed by this delegate that are
 * in functions enclosing it.
 * Params:
 *      fd = function
 *      vars = array to append found variables to
 */
void findAllOuterAccessedVariables(FuncDeclaration *fd, VarDeclarations *vars)
{
    //printf("findAllOuterAccessedVariables(fd: %s)\n", fd.toChars());
    for (Dsymbol *p = fd->parent; p; p = p->parent)
    {
        FuncDeclaration *fdp = p->isFuncDeclaration();
        if (fdp)
        {
            for (size_t i = 0; i < fdp->closureVars.length; i++)
            {
                VarDeclaration *v = fdp->closureVars[i];
                for (size_t j = 0; j < v->nestedrefs.length; j++)
                {
                    FuncDeclaration *fdv = v->nestedrefs[j];
                    if (fdv == fd)
                    {
                        //printf("accessed: %s, type %s\n", v->toChars(), v->type->toChars());
                        vars->push(v);
                    }
                }
            }
        }
    }
}
