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

#include "root/dsystem.h"

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

bool walkPostorder(Expression *e, StoppableVisitor *v);
bool lambdaHasSideEffect(Expression *e);

/**************************************************
 * Front-end expression rewriting should create temporary variables for
 * non trivial sub-expressions in order to:
 *  1. save evaluation order
 *  2. prevent sharing of sub-expression in AST
 */
bool isTrivialExp(Expression *e)
{
    class IsTrivialExp : public StoppableVisitor
    {
    public:
        IsTrivialExp() {}

        void visit(Expression *e)
        {
            /* Bugzilla 11201: CallExp is always non trivial expression,
             * especially for inlining.
             */
            if (e->op == TOKcall)
            {
                stop = true;
                return;
            }

            // stop walking if we determine this expression has side effects
            stop = lambdaHasSideEffect(e);
        }
    };

    IsTrivialExp v;
    return walkPostorder(e, &v) == false;
}

/********************************************
 * Determine if Expression has any side effects.
 */

bool hasSideEffect(Expression *e)
{
    class LambdaHasSideEffect : public StoppableVisitor
    {
    public:
        LambdaHasSideEffect() {}

        void visit(Expression *e)
        {
            // stop walking if we determine this expression has side effects
            stop = lambdaHasSideEffect(e);
        }
    };

    LambdaHasSideEffect v;
    return walkPostorder(e, &v);
}

/********************************************
 * Determine if the call of f, or function type or delegate type t1, has any side effects.
 * Returns:
 *      0   has any side effects
 *      1   nothrow + constant purity
 *      2   nothrow + strong purity
 */

int callSideEffectLevel(FuncDeclaration *f)
{
    /* Bugzilla 12760: ctor call always has side effects.
     */
    if (f->isCtorDeclaration())
        return 0;

    assert(f->type->ty == Tfunction);
    TypeFunction *tf = (TypeFunction *)f->type;
    if (tf->isnothrow)
    {
        PURE purity = f->isPure();
        if (purity == PUREstrong)
            return 2;
        if (purity == PUREconst)
            return 1;
    }
    return 0;
}

int callSideEffectLevel(Type *t)
{
    t = t->toBasetype();

    TypeFunction *tf;
    if (t->ty == Tdelegate)
        tf = (TypeFunction *)((TypeDelegate *)t)->next;
    else
    {
        assert(t->ty == Tfunction);
        tf = (TypeFunction *)t;
    }

    tf->purityLevel();
    PURE purity = tf->purity;
    if (t->ty == Tdelegate && purity > PUREweak)
    {
        if (tf->isMutable())
            purity = PUREweak;
        else if (!tf->isImmutable())
            purity = PUREconst;
    }

    if (tf->isnothrow)
    {
        if (purity == PUREstrong)
            return 2;
        if (purity == PUREconst)
            return 1;
    }
    return 0;
}

bool lambdaHasSideEffect(Expression *e)
{
    switch (e->op)
    {
        // Sort the cases by most frequently used first
        case TOKassign:
        case TOKplusplus:
        case TOKminusminus:
        case TOKdeclaration:
        case TOKconstruct:
        case TOKblit:
        case TOKaddass:
        case TOKminass:
        case TOKcatass:
        case TOKmulass:
        case TOKdivass:
        case TOKmodass:
        case TOKshlass:
        case TOKshrass:
        case TOKushrass:
        case TOKandass:
        case TOKorass:
        case TOKxorass:
        case TOKpowass:
        case TOKin:
        case TOKremove:
        case TOKassert:
        case TOKhalt:
        case TOKdelete:
        case TOKnew:
        case TOKnewanonclass:
            return true;

        case TOKcall:
        {
            CallExp *ce = (CallExp *)e;
            /* Calling a function or delegate that is pure nothrow
             * has no side effects.
             */
            if (ce->e1->type)
            {
                Type *t = ce->e1->type->toBasetype();
                if (t->ty == Tdelegate)
                    t = ((TypeDelegate *)t)->next;
                if (t->ty == Tfunction &&
                    (ce->f ? callSideEffectLevel(ce->f)
                           : callSideEffectLevel(ce->e1->type)) > 0)
                {
                }
                else
                    return true;
            }
            break;
        }

        case TOKcast:
        {
            CastExp *ce = (CastExp *)e;
            /* if:
             *  cast(classtype)func()  // because it may throw
             */
            if (ce->to->ty == Tclass && ce->e1->op == TOKcall && ce->e1->type->ty == Tclass)
                return true;
            break;
        }

        default:
            break;
    }
    return false;
}


/***********************************
 * The result of this expression will be discarded.
 * Print error messages if the operation has no side effects (and hence is meaningless).
 * Returns:
 *      true if expression has no side effects
 */
bool discardValue(Expression *e)
{
    if (lambdaHasSideEffect(e))     // check side-effect shallowly
        return false;
    switch (e->op)
    {
        case TOKcast:
        {
            CastExp *ce = (CastExp *)e;
            if (ce->to->equals(Type::tvoid))
            {
                /*
                 * Don't complain about an expression with no effect if it was cast to void
                 */
                return false;
            }
            break;          // complain
        }

        case TOKerror:
            return false;

        case TOKvar:
        {
            VarDeclaration *v = ((VarExp *)e)->var->isVarDeclaration();
            if (v && (v->storage_class & STCtemp))
            {
                // Bugzilla 5810: Don't complain about an internal generated variable.
                return false;
            }
            break;
        }
        case TOKcall:
            /* Issue 3882: */
            if (global.params.warnings != DIAGNOSTICoff && !global.gag)
            {
                CallExp *ce = (CallExp *)e;
                if (e->type->ty == Tvoid)
                {
                    /* Don't complain about calling void-returning functions with no side-effect,
                     * because purity and nothrow are inferred, and because some of the
                     * runtime library depends on it. Needs more investigation.
                     *
                     * One possible solution is to restrict this message to only be called in hierarchies that
                     * never call assert (and or not called from inside unittest blocks)
                     */
                }
                else if (ce->e1->type)
                {
                    Type *t = ce->e1->type->toBasetype();
                    if (t->ty == Tdelegate)
                        t = ((TypeDelegate *)t)->next;
                    if (t->ty == Tfunction &&
                        (ce->f ? callSideEffectLevel(ce->f)
                               : callSideEffectLevel(ce->e1->type)) > 0)
                    {
                        const char *s;
                        if (ce->f)
                            s = ce->f->toPrettyChars();
                        else if (ce->e1->op == TOKstar)
                        {
                            // print 'fp' if ce->e1 is (*fp)
                            s = ((PtrExp *)ce->e1)->e1->toChars();
                        }
                        else
                            s = ce->e1->toChars();

                        e->warning("calling %s without side effects discards return value of type %s, prepend a cast(void) if intentional",
                                   s, e->type->toChars());
                    }
                }
            }
            return false;

        case TOKscope:
            e->error("%s has no effect", e->toChars());
            return true;

        case TOKandand:
        case TOKoror:
        {
            LogicalExp *aae = (LogicalExp  *)e;
            return discardValue(aae->e2);
        }

        case TOKquestion:
        {
            CondExp *ce = (CondExp *)e;

            /* Bugzilla 6178 & 14089: Either CondExp::e1 or e2 may have
             * redundant expression to make those types common. For example:
             *
             *  struct S { this(int n); int v; alias v this; }
             *  S[int] aa;
             *  aa[1] = 0;
             *
             * The last assignment statement will be rewitten to:
             *
             *  1 in aa ? aa[1].value = 0 : (aa[1] = 0, aa[1].this(0)).value;
             *
             * The last DotVarExp is necessary to take assigned value.
             *
             *  int value = (aa[1] = 0);    // value = aa[1].value
             *
             * To avoid false error, discardValue() should be called only when
             * the both tops of e1 and e2 have actually no side effects.
             */
            if (!lambdaHasSideEffect(ce->e1) &&
                !lambdaHasSideEffect(ce->e2))
            {
                return discardValue(ce->e1) |
                       discardValue(ce->e2);
            }
            return false;
        }

        case TOKcomma:
        {
            CommaExp *ce = (CommaExp *)e;
            /* Check for compiler-generated code of the form  auto __tmp, e, __tmp;
             * In such cases, only check e for side effect (it's OK for __tmp to have
             * no side effect).
             * See Bugzilla 4231 for discussion
             */
            CommaExp *firstComma = ce;
            while (firstComma->e1->op == TOKcomma)
                firstComma = (CommaExp *)firstComma->e1;
            if (firstComma->e1->op == TOKdeclaration &&
                ce->e2->op == TOKvar &&
                ((DeclarationExp *)firstComma->e1)->declaration == ((VarExp*)ce->e2)->var)
            {
                return false;
            }
            // Don't check e1 until we cast(void) the a,b code generation
            //discardValue(ce->e1);
            return discardValue(ce->e2);
        }

        case TOKtuple:
            /* Pass without complaint if any of the tuple elements have side effects.
             * Ideally any tuple elements with no side effects should raise an error,
             * this needs more investigation as to what is the right thing to do.
             */
            if (!hasSideEffect(e))
                break;
            return false;

        default:
            break;
    }
    e->error("%s has no effect in expression (%s)", Token::toChars(e->op), e->toChars());
    return true;
}

/**************************************************
 * Build a temporary variable to copy the value of e into.
 * Params:
 *  stc = storage classes will be added to the made temporary variable
 *  name = name for temporary variable
 *  e = original expression
 * Returns:
 *  Newly created temporary variable.
 */
VarDeclaration *copyToTemp(StorageClass stc, const char *name, Expression *e)
{
    assert(name && name[0] == '_' && name[1] == '_');
    Identifier *id = Identifier::generateId(name);
    ExpInitializer *ez = new ExpInitializer(e->loc, e);
    VarDeclaration *vd = new VarDeclaration(e->loc, e->type, id, ez);
    vd->storage_class = stc;
    vd->storage_class |= STCtemp;
    vd->storage_class |= STCctfe; // temporary is always CTFEable
    return vd;
}

/**************************************************
 * Build a temporary variable to extract e's evaluation, if e is not trivial.
 * Params:
 *  sc = scope
 *  name = name for temporary variable
 *  e0 = a new side effect part will be appended to it.
 *  e = original expression
 *  alwaysCopy = if true, build new temporary variable even if e is trivial.
 * Returns:
 *  When e is trivial and alwaysCopy == false, e itself is returned.
 *  Otherwise, a new VarExp is returned.
 * Note:
 *  e's lvalue-ness will be handled well by STCref or STCrvalue.
 */
Expression *extractSideEffect(Scope *sc, const char *name,
    Expression **e0, Expression *e, bool alwaysCopy = false)
{
    if (!alwaysCopy && isTrivialExp(e))
        return e;

    VarDeclaration *vd = copyToTemp(0, name, e);
    if (e->isLvalue())
        vd->storage_class |= STCref;
    else
        vd->storage_class |= STCrvalue;

    Expression *de = new DeclarationExp(vd->loc, vd);
    Expression *ve = new VarExp(vd->loc, vd);
    de = expressionSemantic(de, sc);
    ve = expressionSemantic(ve, sc);

    *e0 = Expression::combine(*e0, de);
    return ve;
}
