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; }
/********************************************** * 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; }