示例#1
0
		bool ReturnStatement::analyze(semantic::SemanticAnalysis& sa, shptr<semantic::symbol::SymbolTable> symbolTable) const
		{
			auto ret_type = semantic::symbol::Symbol::makeSymbol("return", symbolTable->getCurrentScope())->getCurrentDefinition()->getType();
			auto expr_type = std::make_shared<ast::Type>(ast::Type::Primitive_type::VOID);

			if (expression)
			{
				if (*ret_type == *expr_type)
					sa.reportError("Method returns void, but return statement has expression.", this->expression);
				else
				{
					expr_type = expression->get_type(sa, symbolTable);

					if (expr_type)
					{
						if (!(*ret_type == *expr_type ||
						        (ret_type->isRefType() && expr_type->getPrimitiveType() == ast::Type::Primitive_type::NULL_TYPE)))
							sa.reportError("Mismatched types in return: $type{" + ret_type->getName() + "} and {" + expr_type->getName() + "}", this->expression);
					}
				}
			}
			else if (*ret_type != *expr_type)
				sa.reportError("Method returns $type{" + ret_type->getName() + "} but return statement has no expression", this->getPosition());

			return true;
		}
示例#2
0
ALWAYS_INLINE
bool DataWalker::visitTypedValue(TypedValue rval,
                                 DataFeature& features,
                                 PointerSet& visited,
                                 PointerMap* seenArrs) const {
  if (isRefType(rval.m_type)) {
    if (rval.m_data.pref->isReferenced()) {
      if (markVisited(rval.m_data.pref, features, visited)) {
        // Don't recurse forever; we already went down this path, and
        // stop the walk if we've already got everything we need.
        return canStopWalk(features);
      }
      // Right now consider it circular even if the referenced variant
      // only showed up in one spot.  This could be revisted later.
      features.isCircular = true;
      if (canStopWalk(features)) return true;
    }
    rval = *rval.m_data.pref->cell();
  }

  if (rval.m_type == KindOfObject) {
    features.hasObjectOrResource = true;
    traverseData(rval.m_data.pobj, features, visited);
  } else if (isArrayLikeType(rval.m_type)) {
    traverseData(rval.m_data.parr, features, visited, seenArrs);
  } else if (rval.m_type == KindOfResource) {
    features.hasObjectOrResource = true;
  }
  return canStopWalk(features);
}
示例#3
0
bool tvIsPlausible(TypedValue tv) {
  if (isRefType(tv.m_type)) {
    assertx(tv.m_data.pref);
    assertx(uintptr_t(tv.m_data.pref) % sizeof(void*) == 0);
    assertx(tv.m_data.pref->kindIsValid());
    assertx(tv.m_data.pref->checkCountZ());
    tv = *tv.m_data.pref->cell();
  }
  return cellIsPlausible(tv);
}
示例#4
0
bool cellIsPlausible(const Cell cell) {
  assertx(!isRefType(cell.m_type));

  auto assertPtr = [](const void* ptr) {
    assertx(ptr && (uintptr_t(ptr) % sizeof(ptr) == 0));
  };

  [&] {
    switch (cell.m_type) {
      case KindOfUninit:
      case KindOfNull:
        return;
      case KindOfBoolean:
        assertx(cell.m_data.num == 0 || cell.m_data.num == 1);
        return;
      case KindOfInt64:
      case KindOfDouble:
        return;
      case KindOfPersistentString:
        assertPtr(cell.m_data.pstr);
        assertx(cell.m_data.pstr->kindIsValid());
        assertx(!cell.m_data.pstr->isRefCounted());
        return;
      case KindOfString:
        assertPtr(cell.m_data.pstr);
        assertx(cell.m_data.pstr->kindIsValid());
        assertx(cell.m_data.pstr->checkCountZ());
        return;
      case KindOfPersistentVec:
        assertPtr(cell.m_data.parr);
        assertx(!cell.m_data.parr->isRefCounted());
        assertx(cell.m_data.parr->isVecArray());
        assertx(cell.m_data.parr->isNotDVArray());
        return;
      case KindOfVec:
        assertPtr(cell.m_data.parr);
        assertx(cell.m_data.parr->checkCountZ());
        assertx(cell.m_data.parr->isVecArray());
        assertx(cell.m_data.parr->isNotDVArray());
        return;
      case KindOfPersistentDict:
        assertPtr(cell.m_data.parr);
        assertx(!cell.m_data.parr->isRefCounted());
        assertx(cell.m_data.parr->isDict());
        assertx(cell.m_data.parr->isNotDVArray());
        return;
      case KindOfDict:
        assertPtr(cell.m_data.parr);
        assertx(cell.m_data.parr->checkCountZ());
        assertx(cell.m_data.parr->isDict());
        assertx(cell.m_data.parr->isNotDVArray());
        return;
      case KindOfPersistentKeyset:
        assertPtr(cell.m_data.parr);
        assertx(!cell.m_data.parr->isRefCounted());
        assertx(cell.m_data.parr->isKeyset());
        assertx(cell.m_data.parr->isNotDVArray());
        return;
      case KindOfKeyset:
        assertPtr(cell.m_data.parr);
        assertx(cell.m_data.parr->checkCountZ());
        assertx(cell.m_data.parr->isKeyset());
        assertx(cell.m_data.parr->isNotDVArray());
        return;
      case KindOfPersistentShape:
        if (RuntimeOption::EvalHackArrDVArrs) {
          assertPtr(cell.m_data.parr);
          assertx(!cell.m_data.parr->isRefCounted());
          assertx(cell.m_data.parr->isShape());
          assertx(cell.m_data.parr->isNotDVArray());
          return;
        }
        assertPtr(cell.m_data.parr);
        assertx(cell.m_data.parr->kindIsValid());
        assertx(!cell.m_data.parr->isRefCounted());
        assertx(cell.m_data.parr->isShape());
        assertx(cell.m_data.parr->dvArraySanityCheck());
        return;
      case KindOfShape:
        assertPtr(cell.m_data.parr);
        assertx(cell.m_data.parr->checkCountZ());
        assertx(cell.m_data.parr->isShape());
        if (RuntimeOption::EvalHackArrDVArrs) {
          assertx(cell.m_data.parr->isNotDVArray());
          return;
        }
        assertx(cell.m_data.parr->kindIsValid());
        assertx(cell.m_data.parr->dvArraySanityCheck());
        return;
      case KindOfPersistentArray:
        assertPtr(cell.m_data.parr);
        assertx(cell.m_data.parr->kindIsValid());
        assertx(!cell.m_data.parr->isRefCounted());
        assertx(cell.m_data.parr->isPHPArray());
        assertx(cell.m_data.parr->dvArraySanityCheck());
        return;
      case KindOfArray:
        assertPtr(cell.m_data.parr);
        assertx(cell.m_data.parr->kindIsValid());
        assertx(cell.m_data.parr->checkCountZ());
        assertx(cell.m_data.parr->isPHPArray());
        assertx(cell.m_data.parr->dvArraySanityCheck());
        return;
      case KindOfObject:
        assertPtr(cell.m_data.pobj);
        assertx(cell.m_data.pobj->kindIsValid());
        assertx(cell.m_data.pobj->checkCountZ());
        return;
      case KindOfRecord:
        assertPtr(cell.m_data.prec);
        assertx(cell.m_data.prec->kindIsValid());
        assertx(cell.m_data.prec->checkCount());
        return;
      case KindOfResource:
        assertPtr(cell.m_data.pres);
        assertx(cell.m_data.pres->kindIsValid());
        assertx(cell.m_data.pres->checkCountZ());
        return;
      case KindOfFunc:
        assertPtr(cell.m_data.pfunc);
        assertx(cell.m_data.pfunc->validate());
        return;
      case KindOfClass:
        assertPtr(cell.m_data.pclass);
        assertx(cell.m_data.pclass->validate());
        return;
      case KindOfClsMeth:
        assertx(cell.m_data.pclsmeth->validate());
        return;
      case KindOfRef:
        assertx(!"KindOfRef found in a Cell");
        break;
    }
    not_reached();
  }();

  return true;
}
示例#5
0
bool refIsPlausible(const Ref ref) {
  assertx(isRefType(ref.m_type));
  return tvIsPlausible(ref);
}