Пример #1
0
        static int fp(void *param, FuncDeclaration *f)
        {
            Param3 *p = (Param3 *)param;
            TypeFunction *tf = (TypeFunction *)f->type;
            MATCH m = MATCHexact;

            if (f->isThis())
            {   if (!MODimplicitConv(p->mod, tf->mod))
                    m = MATCHnomatch;
                else if (p->mod != tf->mod)
                    m = MATCHconst;
            }
            if (!inferApplyArgTypesY(tf, p->arguments, 1))
                m = MATCHnomatch;

            if (m > p->match)
            {   p->fd_best = f;
                p->fd_ambig = NULL;
                p->match = m;
            }
            else if (m == p->match)
                p->fd_ambig = f;
            return 0;
        }
Пример #2
0
/**********************************************
 * Determine if it is @safe to cast e from tfrom to tto.
 * Params:
 *      e = expression to be cast
 *      tfrom = type of e
 *      tto = type to cast e to
 * Returns:
 *      true if @safe
 */
bool isSafeCast(Expression *e, Type *tfrom, Type *tto)
{
    // Implicit conversions are always safe
    if (tfrom->implicitConvTo(tto))
        return true;

    if (!tto->hasPointers())
        return true;

    Type *ttob = tto->toBasetype();

    if (ttob->ty == Tclass && tfrom->ty == Tclass)
    {
        ClassDeclaration *cdfrom = tfrom->isClassHandle();
        ClassDeclaration *cdto = ttob->isClassHandle();

        int offset;
        if (!cdfrom->isBaseOf(cdto, &offset))
            return false;

        if (cdfrom->isCPPinterface() || cdto->isCPPinterface())
            return false;

        if (!MODimplicitConv(tfrom->mod, ttob->mod))
            return false;
        return true;
    }

    if (ttob->ty == Tarray && tfrom->ty == Tsarray) // Bugzilla 12502
        tfrom = tfrom->nextOf()->arrayOf();

    if ((ttob->ty == Tarray   && tfrom->ty == Tarray) ||
        (ttob->ty == Tpointer && tfrom->ty == Tpointer))
    {
        Type *ttobn = ttob->nextOf()->toBasetype();
        Type *tfromn = tfrom->nextOf()->toBasetype();

        /* From void[] to anything mutable is unsafe because:
         *  int*[] api;
         *  void[] av = api;
         *  int[] ai = cast(int[]) av;
         *  ai[0] = 7;
         *  *api[0] crash!
         */
        if (tfromn->ty == Tvoid && ttobn->isMutable())
        {
            if (ttob->ty == Tarray && e->op == TOKarrayliteral)
                return true;
            return false;
        }

        // If the struct is opaque we don't know about the struct members then the cast becomes unsafe
        if ((ttobn->ty == Tstruct && !((TypeStruct *)ttobn)->sym->members) ||
            (tfromn->ty == Tstruct && !((TypeStruct *)tfromn)->sym->members))
            return false;

        const bool frompointers = tfromn->hasPointers();
        const bool topointers = ttobn->hasPointers();

        if (frompointers && !topointers && ttobn->isMutable())
            return false;

        if (!frompointers && topointers)
            return false;

        if (!topointers &&
            ttobn->ty != Tfunction && tfromn->ty != Tfunction &&
            (ttob->ty == Tarray || ttobn->size() <= tfromn->size()) &&
            MODimplicitConv(tfromn->mod, ttobn->mod))
        {
            return true;
        }
    }
    return false;
}