
/* 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/canthrow.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 Dsymbol_canThrow(Dsymbol *s, FuncDeclaration *func, bool mustNotThrow);
bool walkPostorder(Expression *e, StoppableVisitor *v);

/********************************************
 * Returns true if the expression may throw exceptions.
 * If 'mustNotThrow' is true, generate an error if it throws
 */

bool canThrow(Expression *e, FuncDeclaration *func, bool mustNotThrow)
{
    //printf("Expression::canThrow(%d) %s\n", mustNotThrow, toChars());

    // stop walking if we determine this expression can throw
    class CanThrow : public StoppableVisitor
    {
        FuncDeclaration *func;
        bool mustNotThrow;

    public:
        CanThrow(FuncDeclaration *func, bool mustNotThrow)
            : func(func), mustNotThrow(mustNotThrow)
        {
        }

        void visit(Expression *)
        {
        }

        void visit(DeclarationExp *de)
        {
            stop = Dsymbol_canThrow(de->declaration, func, mustNotThrow);
        }

        void visit(CallExp *ce)
        {
            if (global.errors && !ce->e1->type)
                return;                       // error recovery

            /* If calling a function or delegate that is typed as nothrow,
             * then this expression cannot throw.
             * Note that pure functions can throw.
             */
            Type *t = ce->e1->type->toBasetype();
            if (ce->f && ce->f == func)
                return;
            if (t->ty == Tfunction && ((TypeFunction *)t)->isnothrow)
                return;
            if (t->ty == Tdelegate && ((TypeFunction *)((TypeDelegate *)t)->next)->isnothrow)
                return;

            if (mustNotThrow)
            {
                if (ce->f)
                {
                    ce->error("%s `%s` is not nothrow",
                        ce->f->kind(), ce->f->toPrettyChars());
                }
                else
                {
                    Expression *e1 = ce->e1;
                    if (e1->op == TOKstar)   // print 'fp' if e1 is (*fp)
                        e1 = ((PtrExp *)e1)->e1;
                    ce->error("`%s` is not nothrow", e1->toChars());
                }
            }
            stop = true;
        }

        void visit(NewExp *ne)
        {
            if (ne->member)
            {
                if (ne->allocator)
                {
                    // Bugzilla 14407
                    Type *t = ne->allocator->type->toBasetype();
                    if (t->ty == Tfunction && !((TypeFunction *)t)->isnothrow)
                    {
                        if (mustNotThrow)
                        {
                            ne->error("%s `%s` is not nothrow",
                                ne->allocator->kind(), ne->allocator->toPrettyChars());
                        }
                        stop = true;
                    }
                }
                // See if constructor call can throw
                Type *t = ne->member->type->toBasetype();
                if (t->ty == Tfunction && !((TypeFunction *)t)->isnothrow)
                {
                    if (mustNotThrow)
                    {
                        ne->error("%s `%s` is not nothrow",
                            ne->member->kind(), ne->member->toPrettyChars());
                    }
                    stop = true;
                }
            }
            // regard storage allocation failures as not recoverable
        }

        void visit(DeleteExp *de)
        {
            Type *tb = de->e1->type->toBasetype();
            AggregateDeclaration *ad = NULL;
            switch (tb->ty)
            {
            case Tclass:
                ad = ((TypeClass *)tb)->sym;
                break;

            case Tpointer:
                tb = ((TypePointer *)tb)->next->toBasetype();
                if (tb->ty == Tstruct)
                    ad = ((TypeStruct *)tb)->sym;
                break;

            case Tarray:
            {
                Type *tv = tb->nextOf()->baseElemOf();
                if (tv->ty == Tstruct)
                {
                    ad = ((TypeStruct *)tv)->sym;
                    break;
                }
            }

            default:
                break;
            }
            if (!ad)
                return;

            if (ad->dtor)
            {
                Type *t = ad->dtor->type->toBasetype();
                if (t->ty == Tfunction && !((TypeFunction *)t)->isnothrow)
                {
                    if (mustNotThrow)
                    {
                        de->error("%s `%s` is not nothrow",
                            ad->dtor->kind(), ad->dtor->toPrettyChars());
                    }
                    stop = true;
                }
            }
            if (ad->aggDelete && tb->ty != Tarray)
            {
                Type *t = ad->aggDelete->type;
                if (t->ty == Tfunction && !((TypeFunction *)t)->isnothrow)
                {
                    if (mustNotThrow)
                    {
                        de->error("%s `%s` is not nothrow",
                            ad->aggDelete->kind(), ad->aggDelete->toPrettyChars());
                    }
                    stop = true;
                }
            }
        }

        void visit(AssignExp *ae)
        {
            // blit-init cannot throw
            if (ae->op == TOKblit)
                return;

            /* Element-wise assignment could invoke postblits.
             */
            Type *t;
            if (ae->type->toBasetype()->ty == Tsarray)
            {
                if (!ae->e2->isLvalue())
                    return;
                t = ae->type;
            }
            else if (ae->e1->op == TOKslice)
                t = ((SliceExp *)ae->e1)->e1->type;
            else
                return;

            Type *tv = t->baseElemOf();
            if (tv->ty != Tstruct)
                return;
            StructDeclaration *sd = ((TypeStruct *)tv)->sym;
            if (!sd->postblit || sd->postblit->type->ty != Tfunction)
                return;

            if (((TypeFunction *)sd->postblit->type)->isnothrow)
                ;
            else
            {
                if (mustNotThrow)
                {
                    ae->error("%s `%s` is not nothrow",
                        sd->postblit->kind(), sd->postblit->toPrettyChars());
                }
                stop = true;
            }
        }

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

    CanThrow ct(func, mustNotThrow);
    return walkPostorder(e, &ct);
}

/**************************************
 * Does symbol, when initialized, throw?
 * Mirrors logic in Dsymbol_toElem().
 */

bool Dsymbol_canThrow(Dsymbol *s, FuncDeclaration *func, bool mustNotThrow)
{
    AttribDeclaration *ad;
    VarDeclaration *vd;
    TemplateMixin *tm;
    TupleDeclaration *td;

    //printf("Dsymbol_toElem() %s\n", s->toChars());
    ad = s->isAttribDeclaration();
    if (ad)
    {
        Dsymbols *decl = ad->include(NULL);
        if (decl && decl->length)
        {
            for (size_t i = 0; i < decl->length; i++)
            {
                s = (*decl)[i];
                if (Dsymbol_canThrow(s, func, mustNotThrow))
                    return true;
            }
        }
    }
    else if ((vd = s->isVarDeclaration()) != NULL)
    {
        s = s->toAlias();
        if (s != vd)
            return Dsymbol_canThrow(s, func, mustNotThrow);
        if (vd->storage_class & STCmanifest)
            ;
        else if (vd->isStatic() || vd->storage_class & (STCextern | STCtls | STCgshared))
            ;
        else
        {
            if (vd->_init)
            {
                ExpInitializer *ie = vd->_init->isExpInitializer();
                if (ie && canThrow(ie->exp, func, mustNotThrow))
                    return true;
            }
            if (vd->needsScopeDtor())
                return canThrow(vd->edtor, func, mustNotThrow);
        }
    }
    else if ((tm = s->isTemplateMixin()) != NULL)
    {
        //printf("%s\n", tm->toChars());
        if (tm->members)
        {
            for (size_t i = 0; i < tm->members->length; i++)
            {
                Dsymbol *sm = (*tm->members)[i];
                if (Dsymbol_canThrow(sm, func, mustNotThrow))
                    return true;
            }
        }
    }
    else if ((td = s->isTupleDeclaration()) != NULL)
    {
        for (size_t i = 0; i < td->objects->length; i++)
        {
            RootObject *o = (*td->objects)[i];
            if (o->dyncast() == DYNCAST_EXPRESSION)
            {
                Expression *eo = (Expression *)o;
                if (eo->op == TOKdsymbol)
                {
                    DsymbolExp *se = (DsymbolExp *)eo;
                    if (Dsymbol_canThrow(se->s, func, mustNotThrow))
                        return true;
                }
            }
        }
    }
    return false;
}
