/**************************************** * Check access to d for expression e.d * Returns true if the declaration is not accessible. */ bool checkAccess(Loc loc, Scope *sc, Expression *e, Declaration *d) { if (sc->flags & SCOPEnoaccesscheck) return false; #if LOG if (e) { printf("checkAccess(%s . %s)\n", e->toChars(), d->toChars()); printf("\te->type = %s\n", e->type->toChars()); } else { printf("checkAccess(%s)\n", d->toPrettyChars()); } #endif if(d->isUnitTestDeclaration()) { // Unittests are always accessible. return false; } if (!e) { if (d->prot().kind == PROTprivate && d->getAccessModule() != sc->module || d->prot().kind == PROTpackage && !hasPackageAccess(sc, d)) { error(loc, "%s %s is not accessible from module %s", d->kind(), d->toPrettyChars(), sc->module->toChars()); return true; } } else if (e->type->ty == Tclass) { // Do access check ClassDeclaration *cd = (ClassDeclaration *)(((TypeClass *)e->type)->sym); if (e->op == TOKsuper) { ClassDeclaration *cd2 = sc->func->toParent()->isClassDeclaration(); if (cd2) cd = cd2; } return checkAccess(cd, loc, sc, d); } else if (e->type->ty == Tstruct) { // Do access check StructDeclaration *cd = (StructDeclaration *)(((TypeStruct *)e->type)->sym); return checkAccess(cd, loc, sc, d); } return false; }
void accessCheck(Loc loc, Scope *sc, Expression *e, Declaration *d) { #if LOG if (e) { printf("accessCheck(%s . %s)\n", e->toChars(), d->toChars()); printf("\te->type = %s\n", e->type->toChars()); } else { //printf("accessCheck(%s)\n", d->toChars()); } #endif if (!e) { if (d->prot() == PROTprivate && d->getModule() != sc->module || d->prot() == PROTpackage && !hasPackageAccess(sc, d)) error(loc, "%s %s.%s is not accessible from %s", d->kind(), d->getModule()->toChars(), d->toChars(), sc->module->toChars()); } else if (e->type->ty == Tclass) { // Do access check ClassDeclaration *cd; cd = (ClassDeclaration *)(((TypeClass *)e->type)->sym); #if 1 if (e->op == TOKsuper) { ClassDeclaration *cd2; cd2 = sc->func->toParent()->isClassDeclaration(); if (cd2) cd = cd2; } #endif cd->accessCheck(loc, sc, d); } else if (e->type->ty == Tstruct) { // Do access check StructDeclaration *cd; cd = (StructDeclaration *)(((TypeStruct *)e->type)->sym); cd->accessCheck(loc, sc, d); } }
void AggregateDeclaration::accessCheck(Loc loc, Scope *sc, Dsymbol *smember) { int result; FuncDeclaration *f = sc->func; AggregateDeclaration *cdscope = sc->getStructClassScope(); enum PROT access; #if LOG printf("AggregateDeclaration::accessCheck() for %s.%s in function %s() in scope %s\n", toChars(), smember->toChars(), f ? f->toChars() : NULL, cdscope ? cdscope->toChars() : NULL); #endif Dsymbol *smemberparent = smember->toParent(); if (!smemberparent || !smemberparent->isAggregateDeclaration()) { #if LOG printf("not an aggregate member\n"); #endif return; // then it is accessible } // BUG: should enable this check //assert(smember->parent->isBaseOf(this, NULL)); if (smemberparent == this) { enum PROT access2 = smember->prot(); result = access2 >= PROTpublic || hasPrivateAccess(f) || isFriendOf(cdscope) || (access2 == PROTpackage && hasPackageAccess(sc, this)); #if LOG printf("result1 = %d\n", result); #endif } else if ((access = this->getAccess(smember)) >= PROTpublic) { result = 1; #if LOG printf("result2 = %d\n", result); #endif } else if (access == PROTpackage && hasPackageAccess(sc, this)) { result = 1; #if LOG printf("result3 = %d\n", result); #endif } else { result = accessCheckX(smember, f, this, cdscope); #if LOG printf("result4 = %d\n", result); #endif } if (!result) { error(loc, "member %s is not accessible", smember->toChars()); } }
/******************************* * Do access check for member of this class, this class being the * type of the 'this' pointer used to access smember. * Returns true if the member is not accessible. */ bool checkAccess(AggregateDeclaration *ad, Loc loc, Scope *sc, Dsymbol *smember) { FuncDeclaration *f = sc->func; AggregateDeclaration *cdscope = sc->getStructClassScope(); #if LOG printf("AggregateDeclaration::checkAccess() for %s.%s in function %s() in scope %s\n", ad->toChars(), smember->toChars(), f ? f->toChars() : NULL, cdscope ? cdscope->toChars() : NULL); #endif Dsymbol *smemberparent = smember->toParent(); if (!smemberparent || !smemberparent->isAggregateDeclaration()) { #if LOG printf("not an aggregate member\n"); #endif return false; // then it is accessible } // BUG: should enable this check //assert(smember->parent->isBaseOf(this, NULL)); bool result; Prot access; if (smemberparent == ad) { Prot access2 = smember->prot(); result = access2.kind >= PROTpublic || hasPrivateAccess(ad, f) || isFriendOf(ad, cdscope) || (access2.kind == PROTpackage && hasPackageAccess(sc, ad)) || ad->getAccessModule() == sc->module; #if LOG printf("result1 = %d\n", result); #endif } else if ((access = getAccess(ad, smember)).kind >= PROTpublic) { result = true; #if LOG printf("result2 = %d\n", result); #endif } else if (access.kind == PROTpackage && hasPackageAccess(sc, ad)) { result = true; #if LOG printf("result3 = %d\n", result); #endif } else { result = isAccessible(smember, f, ad, cdscope); #if LOG printf("result4 = %d\n", result); #endif } if (!result) { ad->error(loc, "member %s is not accessible", smember->toChars()); //printf("smember = %s %s, prot = %d, semanticRun = %d\n", // smember->kind(), smember->toPrettyChars(), smember->prot(), smember->semanticRun); return true; } return false; }