Пример #1
0
void readVarInfo(const AstVar* var, uint16_t& localId, uint16_t& localContext, Context* ctx) {
  VarInfo* info = getInfo<VarInfo>(var);
  uint16_t varFunctionId = info->functionId();
  uint16_t curFunctionId = ctx->currentFunctionId();
  localId = info->localId();
  localContext = 0;

  if (varFunctionId != curFunctionId) {
    InterpreterFunction* varFunction = ctx->functionById(varFunctionId);
    InterpreterFunction* curFunction = ctx->functionById(curFunctionId);

    int32_t varFunctionDeep = varFunction->deepness();
    int32_t curFunctionDeep = curFunction->deepness();
    // var function deepness always >= current function deepness
    localContext = static_cast<uint16_t>(curFunctionDeep - varFunctionDeep);
  } 
}
Пример #2
0
void MMO_ToMicroModelica_::transform()
{
	/* Aca comienza todo el ciclo */
	checkStatement(_c->getStatements());
	checkStatement(_c->getIniStatements());
	
	initialFrame.push(_c->getIniStatements());
	
	
	transformEqList(_c->getIniEquations() , _c->getIniStatements(), NULL );
	transformEqList(_c->getEquations()    , _c->getStatements()   , NULL );
	
	/* Cambiamos los tipos y constantes Booleanas */ 
	for(int i = 0; i < _c->getVarSymbolTable()->count();i++) {
		VarInfo  v = _c->getVarSymbolTable()->varInfo(i);
		string n   = _c->getVarSymbolTable()->varName(i);
		//v->setComment(NULL);
		v->setModification( ChangeModifications(v->modification()));
		if (_pre->find(n) != _pre->end())
			v->setDiscrete();
		
		if ( ( !v->isConstant() ) || v->type()->getType() == TYBOOLEAN) v->setType(ChangeToReal(v->type()));
	}
	ChangePre(_c->getIniEquations());
	ChangePre(_c->getEquations());
}
Пример #3
0
MMO_Expression_::MMO_Expression_ (AST_Expression exp, MMO_ModelData data) :
    _exp (NULL), _data (data), _str (), _equationIndex (0), _expressionOrder (2)
{
  _ri = newMMO_ReplaceInterval (_data->symbols ());
  if (_data->hasAnnotation ())
    {
      _expressionOrder = _data->annotation ()->polyCoeffs ();
    }
  AST_Expression e = _ri->foldTraverse (exp);
  _exp = e;
  _gen = newGenerateDeps (_data);
  _deps = _gen->foldTraverse (exp);
  for (VariableInterval vi = _ri->first (); !_ri->end (); vi = _ri->next ())
    {
      VarInfo v = _data->symbols ()->lookup (vi.name ());
      if (v->isState ())
	{
	  _deps->insert (vi.index (), DEP_STATE_VECTOR);
	}
      else if (v->isAlgebraic ())
	{
	  _deps->insert (vi.index (), DEP_ALGEBRAIC_VECTOR_DEF);
	}
      else if (v->isDiscrete ())
	{
	  _deps->insert (vi.index (), DEP_DISCRETE_VECTOR);
	}
    }
  if (_data->calculateAlgebraics ())
    {
      map<Index, Index> states, discretes;
      _traverseAlgebraics (_deps, _data->lhs (), _deps, &states, &discretes,
			   Index (), DEP_ALGEBRAIC_DEF, -1);
      _traverseAlgebraics (_deps, _data->lhs (), _deps, &states, &discretes,
			   Index (), DEP_ALGEBRAIC_VECTOR_DEF, -1);
    }
  _printer = newMMO_PrintExp (_data->symbols (), _ri, data->packages ());
}
Пример #4
0
void
MMO_Generator_::_variablesInitCode ()
{
  stringstream buffer;
  VarSymbolTable vt = _model->varTable ();
  vt->setPrintEnvironment (VST_INIT);
  if (_model->annotation ()->solver () == ANT_DASSL
      || _model->annotation ()->solver () == ANT_DOPRI)
    {
      vt->setPrintEnvironment (VST_CLASSIC_INIT);
    }
  string indent = _writer->indent (1);
  for (VarInfo vi = vt->begin (); !vt->end (); vi = vt->next ())
    {
      Index idx = vi->index ();
      if (!vi->isConstant () && !vi->isParameter ()
	  && (vi->hasAssignment () || vi->hasStartModifier ()
	      || vi->hasEachModifier ()))
	{
	  buffer << _model->printInitialAssignment (vi, indent);
	  _writer->write (&buffer, WR_START_CODE);
	}
    }
}
Пример #5
0
bool FastQuery::getData(const std::string &varNameStr, void *data,
                        const std::string &varPathStr,
                        const bool collective, const bool bcast)
{
    if (! isValid("FastQuery::getData")) return false;

    std::vector<VarInfo> varInfoList;
    std::vector<VarSpace> varSpaceList;
    unsigned int numVar = metadataMgr->getAllVariables
        (varInfoList, varSpaceList, varPathStr, varNameStr);
    if (numVar == 0) {
        LOGGER(ibis::gVerbose > 0)
            << "Warning -- FastQuery::getData("
            << varPathStr.c_str() << ", " << varNameStr.c_str()
            << ") failed to find the named variable";
        return false;
    }
    int idx=0;
    if (numVar > 1) {
        // pick the best fit variable with the shortest length
        std::string varName = varInfoList[0].getPath();
        int len = varName.size();
        for (unsigned int i=1; i<numVar; i++) {
            if (len > varInfoList[i].getPath().size()) {
                idx = i;
                len = varInfoList[i].getPath().size();
            }
        }
        LOGGER(ibis::gVerbose > 2)
            << "Warning -- FastQuery::getData("
            << varPathStr.c_str() << ", " << varNameStr.c_str()
            << ") found multiple variables with the name, use \""
            << varInfoList[idx].getPath() << "\"";
    }

    VarInfo varInfo = varInfoList[idx];
    VarSpace varSpace = varSpaceList[idx];
    bool berr;
#ifndef FQ_NOMPI
    if (collective == false) {
#endif
    if (varInfo.getSize() == varSpace.getSize()) {
        berr = dataFile->getData(varInfo.getPath(), data);
    }
    else {
        berr = dataFile->getArrayData(varInfo.getPath(),
                                      varSpace.getOffsets(),
                                      varSpace.getCounts(),
                                      varSpace.getStrides(), data);
    }
#ifndef FQ_NOMPI
    } else {
    int mpi_dim = 0; // split data by the first dimension
    std::vector<uint64_t> offsets = varSpace.getOffsets();
    std::vector<uint64_t> counts = varSpace.getCounts();
    std::vector<uint64_t> strides = varSpace.getStrides();
    int nElements = varSpace.getSize();
    unsigned int totalCount = counts[mpi_dim];
    if (totalCount < mpi_size) {
        LOGGER(ibis::gVerbose > 0)
            << "Warning -- IndexBuilder::setData("
            << varPathStr.c_str() << ", " << varNameStr.c_str()
            << "): number of MPI tasks cannot be less than"
            << " the dimension length " << totalCount;
        return false;
    }
    int mpi_len = std::ceil((double)totalCount/(double)mpi_size);
    if (mpi_rank >= totalCount%mpi_len && totalCount%mpi_len != 0) {
        counts[mpi_dim] = mpi_len - 1;
        offsets[mpi_dim] += (mpi_len*mpi_rank -
                             (mpi_rank-totalCount%mpi_len)) *
            strides[mpi_dim];
    }
    else {
        counts[mpi_dim] = mpi_len;
        offsets[mpi_dim] += (mpi_len*mpi_rank)*strides[mpi_dim];
    }
    bool mpi_berr = false;
    FQ::DataType fqType = varInfo.getType();
    void* mpi_data;
    int data_len = counts[mpi_dim]*(nElements/totalCount);
    switch(fqType){
    case FQ::FQT_FLOAT: {
        mpi_data = new float[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_DOUBLE: {
        mpi_data = new double[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_BYTE: {
        mpi_data = new signed char[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_UBYTE: {
        mpi_data = new unsigned char[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_SHORT: {
        mpi_data = new int16_t[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_USHORT: {
        mpi_data = new uint16_t[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_INT: {
        mpi_data = new int32_t[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_UINT: {
        mpi_data = new uint32_t[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_LONG: {
        mpi_data = new int64_t[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    case FQ::FQT_ULONG: {
        mpi_data = new uint64_t[data_len];
        mpi_berr = dataFile->getArrayData(varInfo.getPath(), offsets,
                                          counts, strides, mpi_data);
        break;}
    default:
        LOGGER(ibis::gVerbose > 0)
            << "Warning -- FastQuery::setData("
            << varPathStr.c_str() << ", " << varNameStr.c_str()
            << ") can not handle FQ data type " << fqType;
        mpi_berr = false;
    }

    MPI_Allreduce(&mpi_berr, &berr, 1, MPI_BYTE, MPI_BAND, mpi_comm);

    if (berr) {
        int recvcounts[mpi_size];
        int displs[mpi_size];
        recvcounts[0] = mpi_len*(nElements/totalCount);
        displs[0] = 0;
        for(int i=1; i<mpi_size; i++) {
            if (i >= totalCount%mpi_len && totalCount%mpi_len != 0)
                recvcounts[i] = (mpi_len - 1)*(nElements/totalCount);
            else
                recvcounts[i] = mpi_len*(nElements/totalCount);
            displs[i] = displs[i-1] + recvcounts[i-1];
        }

        switch(fqType){
        case FQ::FQT_FLOAT: {
            MPI_Allgatherv(mpi_data, data_len, MPI_FLOAT, data, recvcounts,
                           displs, MPI_FLOAT, mpi_comm);
            break;}
        case FQ::FQT_DOUBLE: {
            MPI_Allgatherv(mpi_data, data_len, MPI_DOUBLE, data,
                           recvcounts, displs, MPI_DOUBLE, mpi_comm);
            break;}
        case FQ::FQT_BYTE: {
            MPI_Allgatherv(mpi_data, data_len, MPI_CHAR, data, recvcounts,
                           displs, MPI_CHAR, mpi_comm);
            break;}
        case FQ::FQT_UBYTE: {
            MPI_Allgatherv(mpi_data, data_len, MPI_UNSIGNED_CHAR, data,
                           recvcounts, displs, MPI_UNSIGNED_CHAR, mpi_comm);
            break;}
        case FQ::FQT_SHORT: {
            MPI_Allgatherv(mpi_data, data_len, MPI_SHORT, data,
                           recvcounts, displs, MPI_SHORT, mpi_comm);
            break;}
        case FQ::FQT_USHORT: {
            MPI_Allgatherv(mpi_data, data_len, MPI_UNSIGNED_SHORT,
                           data, recvcounts, displs,
                           MPI_UNSIGNED_SHORT, mpi_comm);
            break;}
        case FQ::FQT_INT: {
            MPI_Allgatherv(mpi_data, data_len, MPI_INT, data, recvcounts,
                           displs, MPI_INT, mpi_comm);
            break;}
        case FQ::FQT_UINT: {
            MPI_Allgatherv(mpi_data, data_len, MPI_UNSIGNED, data,
                           recvcounts, displs, MPI_UNSIGNED, mpi_comm);
            break;}
        case FQ::FQT_LONG: {
            MPI_Allgatherv(mpi_data, data_len, MPI_LONG_LONG, data,
                           recvcounts, displs, MPI_LONG_LONG, mpi_comm);
            break;}
        case FQ::FQT_ULONG: {
            MPI_Allgatherv(mpi_data, data_len, MPI_UNSIGNED_LONG_LONG,
                           data, recvcounts, displs,
                           MPI_UNSIGNED_LONG_LONG, mpi_comm);
            break;}
        default:
            berr = false;
            break;
        }
    }
    }
#endif
    if (! berr) {
        LOGGER(ibis::gVerbose > 0)
            << "Warning -- FastQuery::getData("
            << varPathStr.c_str() << ", " << varNameStr.c_str()
            << ") failed to get data from dataset \""
            << varInfo.getPath().c_str() << "\"";
        return false;
    }
    else {
        LOGGER(ibis::gVerbose > 6)
            << "FastQuery::getData("
            << varPathStr.c_str() << ", " << varNameStr.c_str()
            << ") successfully retrieved data from dataset \""
            << varInfo.getPath().c_str() << "\"";
        return true;
    }
} // FastQuery::getData
Пример #6
0
void CheckLeakAutoVar::checkScope(const Token * const startToken,
                                  VarInfo *varInfo,
                                  std::set<unsigned int> notzero)
{
    std::map<unsigned int, std::string> &alloctype = varInfo->alloctype;
    std::map<unsigned int, std::string> &possibleUsage = varInfo->possibleUsage;
    const std::set<unsigned int> conditionalAlloc(varInfo->conditionalAlloc);

    // Allocation functions. key = function name, value = allocation type
    std::map<std::string, std::string> allocFunctions(cfgalloc);
    allocFunctions["malloc"] = "malloc";
    allocFunctions["strdup"] = "malloc";
    allocFunctions["fopen"] = "fopen";

    // Deallocation functions. key = function name, value = allocation type
    std::map<std::string, std::string> deallocFunctions(cfgdealloc);
    deallocFunctions["free"] = "malloc";
    deallocFunctions["fclose"] = "fopen";

    // Parse all tokens
    const Token * const endToken = startToken->link();
    for (const Token *tok = startToken; tok && tok != endToken; tok = tok->next()) {
        // Deallocation and then dereferencing pointer..
        if (tok->varId() > 0) {
            const std::map<unsigned int, std::string>::iterator var = alloctype.find(tok->varId());
            if (var != alloctype.end()) {
                if (var->second == "dealloc" && !Token::Match(tok->previous(), "[;{},=] %var% =")) {
                    deallocUseError(tok, tok->str());
                } else if (Token::simpleMatch(tok->tokAt(-2), "= &")) {
                    varInfo->erase(tok->varId());
                } else if (Token::simpleMatch(tok->previous(), "=")) {
                    varInfo->erase(tok->varId());
                }
            }
        }

        if (tok->str() == "(" && tok->previous()->isName()) {
            functionCall(tok->previous(), varInfo, "");
            tok = tok->link();
            continue;
        }

        // look for end of statement
        if (!Token::Match(tok, "[;{}]") || Token::Match(tok->next(), "[;{}]"))
            continue;
        tok = tok->next();
        if (tok == endToken)
            break;

        // parse statement

        // assignment..
        if (tok && tok->varId() && Token::Match(tok, "%var% =")) {
            // taking address of another variable..
            if (Token::Match(tok->next(), "= %var% [+;]")) {
                if (tok->tokAt(2)->varId() != tok->varId()) {
                    // If variable points at allocated memory => error
                    leakIfAllocated(tok, *varInfo);

                    // no multivariable checking currently => bail out for rhs variables
                    for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) {
                        if (tok2->str() == ";") {
                            break;
                        }
                        if (tok2->varId()) {
                            varInfo->erase(tok2->varId());
                        }
                    }
                }
            }

            // is variable used in rhs?
            bool used_in_rhs = false;
            for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) {
                if (tok2->str() == ";") {
                    break;
                }
                if (tok->varId() == tok2->varId()) {
                    used_in_rhs = true;
                    break;
                }
            }
            // TODO: Better checking how the pointer is used in rhs?
            if (used_in_rhs)
                continue;

            // Variable has already been allocated => error
            if (conditionalAlloc.find(tok->varId()) == conditionalAlloc.end())
                leakIfAllocated(tok, *varInfo);
            varInfo->erase(tok->varId());

            // not a local variable nor argument?
            const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(tok->varId());
            if (var && !var->isArgument() && !var->isLocal()) {
                continue;
            }

            // Don't check reference variables
            if (var && var->isReference())
                continue;

            // allocation?
            if (Token::Match(tok->tokAt(2), "%type% (")) {
                const std::map<std::string, std::string>::const_iterator it = allocFunctions.find(tok->strAt(2));
                if (it != allocFunctions.end()) {
                    alloctype[tok->varId()] = it->second;
                }
            }

            // Assigning non-zero value variable. It might be used to
            // track the execution for a later if condition.
            if (Token::Match(tok->tokAt(2), "%num% ;") && MathLib::toLongNumber(tok->strAt(2)) != 0)
                notzero.insert(tok->varId());
            else if (Token::Match(tok->tokAt(2), "- %type% ;") && tok->tokAt(3)->isUpperCaseName())
                notzero.insert(tok->varId());
            else
                notzero.erase(tok->varId());
        }

        // if/else
        else if (Token::simpleMatch(tok, "if (")) {
            // Parse function calls inside the condition
            for (const Token *innerTok = tok->tokAt(2); innerTok; innerTok = innerTok->next()) {
                if (innerTok->str() == ")")
                    break;
                if (innerTok->str() == "(" && innerTok->previous()->isName()) {
                    std::string dealloc;
                    {
                        const std::map<std::string, std::string>::iterator func = deallocFunctions.find(tok->str());
                        if (func != deallocFunctions.end()) {
                            dealloc = func->second;
                        }
                    }

                    functionCall(innerTok->previous(), varInfo, dealloc);
                    innerTok = innerTok->link();
                }
            }

            const Token *tok2 = tok->linkAt(1);
            if (Token::simpleMatch(tok2, ") {")) {
                VarInfo varInfo1(*varInfo);
                VarInfo varInfo2(*varInfo);

                if (Token::Match(tok->next(), "( %var% )")) {
                    varInfo2.erase(tok->tokAt(2)->varId());
                    if (notzero.find(tok->tokAt(2)->varId()) != notzero.end())
                        varInfo2.clear();
                } else if (Token::Match(tok->next(), "( ! %var% )|&&")) {
                    varInfo1.erase(tok->tokAt(3)->varId());
                } else if (Token::Match(tok->next(), "( %var% ( ! %var% ) )|&&")) {
                    varInfo1.erase(tok->tokAt(5)->varId());
                }

                checkScope(tok2->next(), &varInfo1, notzero);
                tok2 = tok2->linkAt(1);
                if (Token::simpleMatch(tok2, "} else {")) {
                    checkScope(tok2->tokAt(2), &varInfo2, notzero);
                    tok = tok2->linkAt(2)->previous();
                } else {
                    tok = tok2->previous();
                }

                VarInfo old;
                old.swap(*varInfo);

                // Conditional allocation in varInfo1
                std::map<unsigned int, std::string>::const_iterator it;
                for (it = varInfo1.alloctype.begin(); it != varInfo1.alloctype.end(); ++it) {
                    if (varInfo2.alloctype.find(it->first) == varInfo2.alloctype.end() &&
                        old.alloctype.find(it->first) == old.alloctype.end()) {
                        varInfo->conditionalAlloc.insert(it->first);
                    }
                }

                // Conditional allocation in varInfo2
                for (it = varInfo2.alloctype.begin(); it != varInfo2.alloctype.end(); ++it) {
                    if (varInfo1.alloctype.find(it->first) == varInfo1.alloctype.end() &&
                        old.alloctype.find(it->first) == old.alloctype.end()) {
                        varInfo->conditionalAlloc.insert(it->first);
                    }
                }

                // Conditional allocation/deallocation
                for (it = varInfo1.alloctype.begin(); it != varInfo1.alloctype.end(); ++it) {
                    if (it->second == "dealloc" && conditionalAlloc.find(it->first) != conditionalAlloc.end()) {
                        varInfo->conditionalAlloc.erase(it->first);
                        varInfo2.erase(it->first);
                    }
                }
                for (it = varInfo2.alloctype.begin(); it != varInfo2.alloctype.end(); ++it) {
                    if (it->second == "dealloc" && conditionalAlloc.find(it->first) != conditionalAlloc.end()) {
                        varInfo->conditionalAlloc.erase(it->first);
                        varInfo1.erase(it->first);
                    }
                }

                alloctype.insert(varInfo1.alloctype.begin(), varInfo1.alloctype.end());
                alloctype.insert(varInfo2.alloctype.begin(), varInfo2.alloctype.end());

                possibleUsage.insert(varInfo1.possibleUsage.begin(), varInfo1.possibleUsage.end());
                possibleUsage.insert(varInfo2.possibleUsage.begin(), varInfo2.possibleUsage.end());
            }
        }

        // unknown control..
        else if (Token::Match(tok, "%type% (") && Token::simpleMatch(tok->linkAt(1), ") {")) {
            varInfo->clear();
            break;
        }

        // Function call..
        else if (Token::Match(tok, "%type% (") && tok->str() != "return") {
            std::string dealloc;
            {
                const std::map<std::string, std::string>::iterator func = deallocFunctions.find(tok->str());
                if (func != deallocFunctions.end()) {
                    dealloc = func->second;
                }
            }

            functionCall(tok, varInfo, dealloc);

            tok = tok->next()->link();

            // Handle scopes that might be noreturn
            if (dealloc.empty() && Token::simpleMatch(tok, ") ; }")) {
                const std::string &functionName(tok->link()->previous()->str());
                bool unknown = false;
                if (cfgignore.find(functionName) == cfgignore.end() &&
                    cfguse.find(functionName) == cfguse.end() &&
                    _tokenizer->IsScopeNoReturn(tok->tokAt(2), &unknown)) {
                    if (unknown) {
                        //const std::string &functionName(tok->link()->previous()->str());
                        varInfo->possibleUsageAll(functionName);
                    } else {
                        varInfo->clear();
                    }
                }
            }

            continue;
        }

        // return
        else if (tok->str() == "return" || tok->str() == "throw") {
            ret(tok, *varInfo);
            varInfo->clear();
        }
    }
}
Пример #7
0
void CheckLeakAutoVar::checkScope(const Token * const startToken,
                                  VarInfo *varInfo,
                                  std::set<unsigned int> notzero)
{
    std::map<unsigned int, int> &alloctype = varInfo->alloctype;
    std::map<unsigned int, std::string> &possibleUsage = varInfo->possibleUsage;
    const std::set<unsigned int> conditionalAlloc(varInfo->conditionalAlloc);

    // Parse all tokens
    const Token * const endToken = startToken->link();
    for (const Token *tok = startToken; tok && tok != endToken; tok = tok->next()) {
        // Deallocation and then dereferencing pointer..
        if (tok->varId() > 0) {
            const std::map<unsigned int, int>::iterator var = alloctype.find(tok->varId());
            if (var != alloctype.end()) {
                if (var->second == DEALLOC && !Token::Match(tok->previous(), "[;{},=] %var% =")) {
                    deallocUseError(tok, tok->str());
                } else if (Token::simpleMatch(tok->tokAt(-2), "= &")) {
                    varInfo->erase(tok->varId());
                } else if (tok->strAt(-1) == "=") {
                    varInfo->erase(tok->varId());
                }
            } else if (Token::Match(tok->previous(), "& %var% = %var% ;")) {
                varInfo->referenced.insert(tok->tokAt(2)->varId());
            }
        }

        if (tok->str() == "(" && tok->previous()->isName()) {
            functionCall(tok->previous(), varInfo, NOALLOC);
            tok = tok->link();
            continue;
        }

        // look for end of statement
        if (!Token::Match(tok, "[;{}]") || Token::Match(tok->next(), "[;{}]"))
            continue;
        tok = tok->next();
        if (!tok || tok == endToken)
            break;

        // parse statement

        // assignment..
        if (tok->varId() && Token::Match(tok, "%var% =")) {
            // taking address of another variable..
            if (Token::Match(tok->next(), "= %var% [+;]")) {
                if (tok->tokAt(2)->varId() != tok->varId()) {
                    // If variable points at allocated memory => error
                    leakIfAllocated(tok, *varInfo);

                    // no multivariable checking currently => bail out for rhs variables
                    for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) {
                        if (tok2->str() == ";") {
                            break;
                        }
                        if (tok2->varId()) {
                            varInfo->erase(tok2->varId());
                        }
                    }
                }
            }

            // is variable used in rhs?
            bool used_in_rhs = false;
            for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) {
                if (tok2->str() == ";") {
                    break;
                }
                if (tok->varId() == tok2->varId()) {
                    used_in_rhs = true;
                    break;
                }
            }
            // TODO: Better checking how the pointer is used in rhs?
            if (used_in_rhs)
                continue;

            // Variable has already been allocated => error
            if (conditionalAlloc.find(tok->varId()) == conditionalAlloc.end())
                leakIfAllocated(tok, *varInfo);
            varInfo->erase(tok->varId());

            // not a local variable nor argument?
            const Variable *var = tok->variable();
            if (var && !var->isArgument() && !var->isLocal()) {
                continue;
            }

            // Don't check reference variables
            if (var && var->isReference())
                continue;

            // allocation?
            if (Token::Match(tok->tokAt(2), "%type% (")) {
                int i = _settings->library.alloc(tok->tokAt(2));
                if (i > 0) {
                    alloctype[tok->varId()] = i;
                }
            }

            // Assigning non-zero value variable. It might be used to
            // track the execution for a later if condition.
            if (Token::Match(tok->tokAt(2), "%num% ;") && MathLib::toLongNumber(tok->strAt(2)) != 0)
                notzero.insert(tok->varId());
            else if (Token::Match(tok->tokAt(2), "- %type% ;") && tok->tokAt(3)->isUpperCaseName())
                notzero.insert(tok->varId());
            else
                notzero.erase(tok->varId());
        }

        // if/else
        else if (Token::simpleMatch(tok, "if (")) {
            // Parse function calls inside the condition
            for (const Token *innerTok = tok->tokAt(2); innerTok; innerTok = innerTok->next()) {
                if (innerTok->str() == ")")
                    break;
                if (innerTok->str() == "(" && innerTok->previous()->isName()) {
                    const int deallocId = _settings->library.dealloc(tok);
                    functionCall(innerTok->previous(), varInfo, deallocId);
                    innerTok = innerTok->link();
                }
            }

            const Token *tok2 = tok->linkAt(1);
            if (Token::simpleMatch(tok2, ") {")) {
                VarInfo varInfo1(*varInfo);  // VarInfo for if code
                VarInfo varInfo2(*varInfo);  // VarInfo for else code

                if (Token::Match(tok->next(), "( %var% )")) {
                    varInfo2.erase(tok->tokAt(2)->varId());
                    if (notzero.find(tok->tokAt(2)->varId()) != notzero.end())
                        varInfo2.clear();
                } else if (Token::Match(tok->next(), "( ! %var% )|&&")) {
                    varInfo1.erase(tok->tokAt(3)->varId());
                } else if (Token::Match(tok->next(), "( %var% ( ! %var% ) )|&&")) {
                    varInfo1.erase(tok->tokAt(5)->varId());
                } else if (Token::Match(tok->next(), "( %var% < 0 )|&&")) {
                    varInfo1.erase(tok->tokAt(2)->varId());
                } else if (Token::Match(tok->next(), "( 0 > %var% )|&&")) {
                    varInfo1.erase(tok->tokAt(4)->varId());
                } else if (Token::Match(tok->next(), "( %var% > 0 )|&&")) {
                    varInfo2.erase(tok->tokAt(2)->varId());
                } else if (Token::Match(tok->next(), "( 0 < %var% )|&&")) {
                    varInfo2.erase(tok->tokAt(4)->varId());
                }

                checkScope(tok2->next(), &varInfo1, notzero);
                tok2 = tok2->linkAt(1);
                if (Token::simpleMatch(tok2, "} else {")) {
                    checkScope(tok2->tokAt(2), &varInfo2, notzero);
                    tok = tok2->linkAt(2)->previous();
                } else {
                    tok = tok2->previous();
                }

                VarInfo old;
                old.swap(*varInfo);

                // Conditional allocation in varInfo1
                std::map<unsigned int, int>::const_iterator it;
                for (it = varInfo1.alloctype.begin(); it != varInfo1.alloctype.end(); ++it) {
                    if (varInfo2.alloctype.find(it->first) == varInfo2.alloctype.end() &&
                        old.alloctype.find(it->first) == old.alloctype.end()) {
                        varInfo->conditionalAlloc.insert(it->first);
                    }
                }

                // Conditional allocation in varInfo2
                for (it = varInfo2.alloctype.begin(); it != varInfo2.alloctype.end(); ++it) {
                    if (varInfo1.alloctype.find(it->first) == varInfo1.alloctype.end() &&
                        old.alloctype.find(it->first) == old.alloctype.end()) {
                        varInfo->conditionalAlloc.insert(it->first);
                    }
                }

                // Conditional allocation/deallocation
                for (it = varInfo1.alloctype.begin(); it != varInfo1.alloctype.end(); ++it) {
                    if (it->second == DEALLOC && conditionalAlloc.find(it->first) != conditionalAlloc.end()) {
                        varInfo->conditionalAlloc.erase(it->first);
                        varInfo2.erase(it->first);
                    }
                }
                for (it = varInfo2.alloctype.begin(); it != varInfo2.alloctype.end(); ++it) {
                    if (it->second == DEALLOC && conditionalAlloc.find(it->first) != conditionalAlloc.end()) {
                        varInfo->conditionalAlloc.erase(it->first);
                        varInfo1.erase(it->first);
                    }
                }

                alloctype.insert(varInfo1.alloctype.begin(), varInfo1.alloctype.end());
                alloctype.insert(varInfo2.alloctype.begin(), varInfo2.alloctype.end());

                possibleUsage.insert(varInfo1.possibleUsage.begin(), varInfo1.possibleUsage.end());
                possibleUsage.insert(varInfo2.possibleUsage.begin(), varInfo2.possibleUsage.end());
            }
        }

        // unknown control..
        else if (Token::Match(tok, "%type% (") && Token::simpleMatch(tok->linkAt(1), ") {")) {
            varInfo->clear();
            break;
        }

        // Function call..
        else if (Token::Match(tok, "%type% (") && tok->str() != "return") {
            const int dealloc = _settings->library.dealloc(tok);

            functionCall(tok, varInfo, dealloc);

            tok = tok->next()->link();

            // Handle scopes that might be noreturn
            if (dealloc == NOALLOC && Token::simpleMatch(tok, ") ; }")) {
                const std::string &functionName(tok->link()->previous()->str());
                bool unknown = false;
                if (_tokenizer->IsScopeNoReturn(tok->tokAt(2), &unknown)) {
                    if (!unknown)
                        varInfo->clear();
                    else if (_settings->library.leakignore.find(functionName) == _settings->library.leakignore.end() &&
                             _settings->library.use.find(functionName) == _settings->library.use.end())
                        varInfo->possibleUsageAll(functionName);
                }
            }

            continue;
        }

        // return
        else if (tok->str() == "return") {
            ret(tok, *varInfo);
            varInfo->clear();
        }

        // goto => weird execution path
        else if (tok->str() == "goto") {
            varInfo->clear();
        }

        // continue/break
        else if (Token::Match(tok, "continue|break ;")) {
            varInfo->clear();
        }

        // throw
        // TODO: if the execution leave the function then treat it as return
        else if (tok->str() == "throw") {
            varInfo->clear();
        }
    }
}
Пример #8
0
Type TypeCheck_::check_expression(AST_Expression e)
{
  Type ct,t1,t2,t;
  switch (e->expressionType()) {
  case EXPBINOP:
  {
    AST_Expression_BinOp b = e->getAsBinOp();
    return check_binop(b->left() , b->right() , b->binopType());
  }
  case EXPUMINUS:
  {
    AST_Expression_UMinus b = e->getAsUMinus();
    t = check_expression(b->exp());
    if ( check_equal(t , T("Integer")) or check_equal(t , T("Real")) ) return t;
    throw "Type Error (3)";
  }

  case EXPOUTPUT :
  {
    AST_Expression_Output b = e->getAsOutput();
    return check_expression(b->expressionList()->front() );
  }

  case EXPIF:
  {
    AST_Expression_If b = e->getAsIf();
    ct = check_expression(b->condition() );
    t1 = check_expression(b->then() );
    t2 = check_expression(b->else_exp()); // Falta el elseIF
    if ( !check_equal(ct, T("Boolean")) ) throw "Type Error (4)";
    if ( !check_equal(t1,t2) ) throw "Type Error (5)";
    return t1;

  }

  case EXPCALL:
  {
    // Añadir las funciones en la listaaaa de variables
    AST_Expression_Call c = e->getAsCall();
    if ( toStr(c->name()) == "sample" ) return  T("Boolean");
    if ( toStr(c->name()) == "pre" ) 		
		return  check_expression(c->arguments()->front());
	return T("Real");
  }

  case EXPCOMPREF:
  {
    AST_Expression_ComponentReference b = e->getAsComponentReference();

    VarInfo  tt = varEnv->lookup(  toStr(b->names()->front()) );

    if (tt == NULL) {
      cerr << "Var:" <<  b->names()->front() << ":";
      throw "Variable no existe (8)";
    }
    if (b->indexes()->front()->size() == 0)
      return tt->type();
    else {
      Type t = tt->type();
      AST_ExpressionListIterator exit;
      foreach(exit , b->indexes()->front() )
      if (t->getType() == TYARRAY)
        t = t->getAsArray()->arrayOf();
      else throw "Type Error (7)";
      return t;
    }

    break;
  }
  case EXPDERIVATIVE:
    return T("Real");
  case EXPBOOLEAN:
    return T("Boolean");
  case EXPSTRING:
    return T("String");
  case EXPREAL:
    return T("Real");
  case EXPINTEGER:
    return T("Integer");
  case EXPBOOLEANNOT:
  {
    AST_Expression_BooleanNot b = e->getAsBooleanNot();
    t = check_expression(b->exp());
    if ( !check_equal(t, T("Boolean")) ) throw "Type Error (6)";
    return t;
  }
  default:
    throw "No implrementado aun! (check_expression)";

  }
}
Пример #9
0
int
MMO_EvalInitExp_::foldTraverseElement (AST_Expression exp)
{
  int ret = 0;
  switch (exp->expressionType ())
    {
    case EXPCOMPREF:
      {
	AST_Expression_ComponentReference cr = exp->getAsComponentReference ();
	VarInfo vi = _vt->lookup (cr->name ());
	if (vi == NULL)
	  {
	    Error::getInstance ()->add (exp->lineNum (),
	    EM_IR | EM_VARIABLE_NOT_FOUND,
					ER_Error, "%s", cr->name ().c_str ());
	    return (ret);
	  }
	if (!vi->isConstant ())
	  {
	    Error::getInstance ()->add (
		exp->lineNum (), EM_IR | EM_INIT_EXP, ER_Error,
		"Only constants allowed inside initial expressions. %s",
		cr->name ().c_str ());
	    return (ret);
	  }
	return (vi->value ());
      }
    case EXPBOOLEAN:
      {
	AST_Expression_Boolean eb = exp->getAsBoolean ();
	if (eb->value ())
	  {
	    return (1);
	  }
	else
	  {
	    return (0);
	  }
      }
    case EXPBOOLEANNOT:
      {
	AST_Expression_BooleanNot ebn = exp->getAsBooleanNot ();
	int res = foldTraverse (ebn->exp ());
	if (res == 0)
	  {
	    return (1);
	  }
	else
	  {
	    return (0);
	  }
      }
    case EXPREAL:
      Error::getInstance ()->add (
	  0, EM_IR | EM_INIT_EXP, ER_Warning,
	  "Implicit conversion from Real to Integer, in initial expression.");
      return (exp->getAsReal ()->val ());
    case EXPINTEGER:
      return (exp->getAsInteger ()->val ());
    default:
      Error::getInstance ()->add (
	  0,
	  EM_IR | EM_INIT_EXP,
	  ER_Warning,
	  "Initial expression not recognized, returning zero as default value.");
      break;
    }
  return (ret);
}
Пример #10
0
void CheckLeakAutoVar::checkScope(const Token * const startToken,
                                  VarInfo *varInfo,
                                  std::set<unsigned int> notzero)
{
    std::map<unsigned int, VarInfo::AllocInfo> &alloctype = varInfo->alloctype;
    std::map<unsigned int, std::string> &possibleUsage = varInfo->possibleUsage;
    const std::set<unsigned int> conditionalAlloc(varInfo->conditionalAlloc);

    // Parse all tokens
    const Token * const endToken = startToken->link();
    for (const Token *tok = startToken; tok && tok != endToken; tok = tok->next()) {
        if (!tok->scope()->isExecutable()) {
            tok = tok->scope()->classEnd;
            if (!tok) // Ticket #6666 (crash upon invalid code)
                break;
        }

        // Deallocation and then dereferencing pointer..
        if (tok->varId() > 0) {
            const std::map<unsigned int, VarInfo::AllocInfo>::const_iterator var = alloctype.find(tok->varId());
            if (var != alloctype.end()) {
                if (var->second.status == VarInfo::DEALLOC && tok->strAt(-1) != "&" && (!Token::Match(tok, "%name% =") || tok->strAt(-1) == "*")) {
                    deallocUseError(tok, tok->str());
                } else if (Token::simpleMatch(tok->tokAt(-2), "= &")) {
                    varInfo->erase(tok->varId());
                } else if (tok->strAt(-1) == "=") {
                    varInfo->erase(tok->varId());
                }
            } else if (Token::Match(tok->previous(), "& %name% = %var% ;")) {
                varInfo->referenced.insert(tok->tokAt(2)->varId());
            }
        }

        if (tok->str() == "(" && tok->previous()->isName()) {
            VarInfo::AllocInfo allocation(0, VarInfo::NOALLOC);
            functionCall(tok->previous(), varInfo, allocation);
            tok = tok->link();
            continue;
        }

        // look for end of statement
        if (!Token::Match(tok, "[;{}]") || Token::Match(tok->next(), "[;{}]"))
            continue;

        tok = tok->next();
        if (!tok || tok == endToken)
            break;

        // parse statement, skip to last member
        while (Token::Match(tok, "%name% ::|. %name% !!("))
            tok = tok->tokAt(2);

        // assignment..
        if (Token::Match(tok, "%var% =")) {
            // taking address of another variable..
            if (Token::Match(tok->next(), "= %var% [+;]")) {
                if (tok->tokAt(2)->varId() != tok->varId()) {
                    // If variable points at allocated memory => error
                    leakIfAllocated(tok, *varInfo);

                    // no multivariable checking currently => bail out for rhs variables
                    for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) {
                        if (tok2->str() == ";") {
                            break;
                        }
                        if (tok2->varId()) {
                            varInfo->erase(tok2->varId());
                        }
                    }
                }
            }

            // is variable used in rhs?
            bool used_in_rhs = false;
            for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) {
                if (tok2->str() == ";") {
                    break;
                }
                if (tok->varId() == tok2->varId()) {
                    used_in_rhs = true;
                    break;
                }
            }
            // TODO: Better checking how the pointer is used in rhs?
            if (used_in_rhs)
                continue;

            // Variable has already been allocated => error
            if (conditionalAlloc.find(tok->varId()) == conditionalAlloc.end())
                leakIfAllocated(tok, *varInfo);
            varInfo->erase(tok->varId());

            // not a local variable nor argument?
            const Variable *var = tok->variable();
            if (var && !var->isArgument() && (!var->isLocal() || var->isStatic()))
                continue;

            // Don't check reference variables
            if (var && var->isReference())
                continue;

            // non-pod variable
            if (_tokenizer->isCPP()) {
                if (!var)
                    continue;
                // Possibly automatically deallocated memory
                if (!var->typeStartToken()->isStandardType() && Token::Match(tok, "%var% = new"))
                    continue;
            }

            // allocation?
            if (tok->next()->astOperand2() && Token::Match(tok->next()->astOperand2()->previous(), "%type% (")) {
                int i = _settings->library.alloc(tok->next()->astOperand2()->previous());
                if (i > 0) {
                    alloctype[tok->varId()].type = i;
                    alloctype[tok->varId()].status = VarInfo::ALLOC;
                }
            } else if (_tokenizer->isCPP() && tok->strAt(2) == "new") {
                alloctype[tok->varId()].type = -1;
                alloctype[tok->varId()].status = VarInfo::ALLOC;
            }

            // Assigning non-zero value variable. It might be used to
            // track the execution for a later if condition.
            if (Token::Match(tok->tokAt(2), "%num% ;") && MathLib::toLongNumber(tok->strAt(2)) != 0)
                notzero.insert(tok->varId());
            else if (Token::Match(tok->tokAt(2), "- %type% ;") && tok->tokAt(3)->isUpperCaseName())
                notzero.insert(tok->varId());
            else
                notzero.erase(tok->varId());
        }

        // if/else
        else if (Token::simpleMatch(tok, "if (")) {
            // Parse function calls inside the condition
            for (const Token *innerTok = tok->tokAt(2); innerTok; innerTok = innerTok->next()) {
                if (innerTok->str() == ")")
                    break;
                if (innerTok->str() == "(" && innerTok->previous()->isName()) {
                    VarInfo::AllocInfo allocation(_settings->library.dealloc(tok), VarInfo::DEALLOC);
                    if (allocation.type == 0)
                        allocation.status = VarInfo::NOALLOC;
                    functionCall(innerTok->previous(), varInfo, allocation);
                    innerTok = innerTok->link();
                }
            }

            const Token *tok2 = tok->linkAt(1);
            if (Token::simpleMatch(tok2, ") {")) {
                VarInfo varInfo1(*varInfo);  // VarInfo for if code
                VarInfo varInfo2(*varInfo);  // VarInfo for else code

                // Recursively scan variable comparisons in condition
                std::stack<const Token *> tokens;
                tokens.push(tok->next()->astOperand2());
                while (!tokens.empty()) {
                    const Token *tok3 = tokens.top();
                    tokens.pop();
                    if (!tok3)
                        continue;
                    if (tok3->str() == "&&") {
                        tokens.push(tok3->astOperand1());
                        tokens.push(tok3->astOperand2());
                        continue;
                    }
                    if (tok3->str() == "(" && Token::Match(tok3->astOperand1(), "UNLIKELY|LIKELY")) {
                        tokens.push(tok3->astOperand2());
                        continue;
                    }

                    const Token *vartok = nullptr;
                    if (astIsVariableComparison(tok3, "!=", "0", &vartok)) {
                        varInfo2.erase(vartok->varId());
                        if (notzero.find(vartok->varId()) != notzero.end())
                            varInfo2.clear();
                    } else if (astIsVariableComparison(tok3, "==", "0", &vartok)) {
                        varInfo1.erase(vartok->varId());
                    } else if (astIsVariableComparison(tok3, "<", "0", &vartok)) {
                        varInfo1.erase(vartok->varId());
                    } else if (astIsVariableComparison(tok3, ">", "0", &vartok)) {
                        varInfo2.erase(vartok->varId());
                    } else if (astIsVariableComparison(tok3, "==", "-1", &vartok)) {
                        varInfo1.erase(vartok->varId());
                    }
                }

                checkScope(tok2->next(), &varInfo1, notzero);
                tok2 = tok2->linkAt(1);
                if (Token::simpleMatch(tok2, "} else {")) {
                    checkScope(tok2->tokAt(2), &varInfo2, notzero);
                    tok = tok2->linkAt(2)->previous();
                } else {
                    tok = tok2->previous();
                }

                VarInfo old;
                old.swap(*varInfo);

                // Conditional allocation in varInfo1
                std::map<unsigned int, VarInfo::AllocInfo>::const_iterator it;
                for (it = varInfo1.alloctype.begin(); it != varInfo1.alloctype.end(); ++it) {
                    if (varInfo2.alloctype.find(it->first) == varInfo2.alloctype.end() &&
                        old.alloctype.find(it->first) == old.alloctype.end()) {
                        varInfo->conditionalAlloc.insert(it->first);
                    }
                }

                // Conditional allocation in varInfo2
                for (it = varInfo2.alloctype.begin(); it != varInfo2.alloctype.end(); ++it) {
                    if (varInfo1.alloctype.find(it->first) == varInfo1.alloctype.end() &&
                        old.alloctype.find(it->first) == old.alloctype.end()) {
                        varInfo->conditionalAlloc.insert(it->first);
                    }
                }

                // Conditional allocation/deallocation
                for (it = varInfo1.alloctype.begin(); it != varInfo1.alloctype.end(); ++it) {
                    if (it->second.status == VarInfo::DEALLOC && conditionalAlloc.find(it->first) != conditionalAlloc.end()) {
                        varInfo->conditionalAlloc.erase(it->first);
                        varInfo2.erase(it->first);
                    }
                }
                for (it = varInfo2.alloctype.begin(); it != varInfo2.alloctype.end(); ++it) {
                    if (it->second.status == VarInfo::DEALLOC && conditionalAlloc.find(it->first) != conditionalAlloc.end()) {
                        varInfo->conditionalAlloc.erase(it->first);
                        varInfo1.erase(it->first);
                    }
                }

                alloctype.insert(varInfo1.alloctype.begin(), varInfo1.alloctype.end());
                alloctype.insert(varInfo2.alloctype.begin(), varInfo2.alloctype.end());

                possibleUsage.insert(varInfo1.possibleUsage.begin(), varInfo1.possibleUsage.end());
                possibleUsage.insert(varInfo2.possibleUsage.begin(), varInfo2.possibleUsage.end());
            }
        }

        // unknown control.. (TODO: handle loops)
        else if ((Token::Match(tok, "%type% (") && Token::simpleMatch(tok->linkAt(1), ") {")) || Token::simpleMatch(tok, "do {")) {
            varInfo->clear();
            break;
        }

        // return
        else if (tok->str() == "return") {
            ret(tok, *varInfo);
            varInfo->clear();
        }

        // throw
        else if (_tokenizer->isCPP() && tok->str() == "throw") {
            bool tryFound = false;
            const Scope* scope = tok->scope();
            while (scope && scope->isExecutable()) {
                if (scope->type == Scope::eTry)
                    tryFound = true;
                scope = scope->nestedIn;
            }
            // If the execution leaves the function then treat it as return
            if (!tryFound)
                ret(tok, *varInfo);
            varInfo->clear();
        }

        // Function call..
        else if (Token::Match(tok, "%type% (")) {
            VarInfo::AllocInfo allocation(_settings->library.dealloc(tok), VarInfo::DEALLOC);
            if (allocation.type == 0)
                allocation.status = VarInfo::NOALLOC;
            functionCall(tok, varInfo, allocation);

            tok = tok->next()->link();

            // Handle scopes that might be noreturn
            if (allocation.status == VarInfo::NOALLOC && Token::simpleMatch(tok, ") ; }")) {
                const std::string &functionName(tok->link()->previous()->str());
                bool unknown = false;
                if (_tokenizer->IsScopeNoReturn(tok->tokAt(2), &unknown)) {
                    if (!unknown)
                        varInfo->clear();
                    else if (_settings->library.leakignore.find(functionName) == _settings->library.leakignore.end() &&
                             _settings->library.use.find(functionName) == _settings->library.use.end())
                        varInfo->possibleUsageAll(functionName);
                }
            }

            continue;
        }

        // delete
        else if (_tokenizer->isCPP() && tok->str() == "delete") {
            if (tok->strAt(1) == "[")
                tok = tok->tokAt(3);
            else
                tok = tok->next();
            while (Token::Match(tok, "%name% ::|."))
                tok = tok->tokAt(2);
            if (tok->varId() && tok->strAt(1) != "[") {
                VarInfo::AllocInfo allocation(-1, VarInfo::DEALLOC);
                changeAllocStatus(varInfo, allocation, tok, tok);
            }
        }

        // goto => weird execution path
        else if (tok->str() == "goto") {
            varInfo->clear();
        }

        // continue/break
        else if (Token::Match(tok, "continue|break ;")) {
            varInfo->clear();
        }
    }
}
Пример #11
0
VOID Image(IMG img, VOID *v)
{
    cerr << "Loading image " << IMG_Name(img) << endl;

    /* Find main. We won't do anything before main starts. */
    RTN rtn = RTN_FindByName(img, "main");
    if(RTN_Valid(rtn))
    {
	RTN_Open(rtn);
	RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)callBeforeMain, IARG_END);
	RTN_Close(rtn);
    }

    /* Go over all the allocation routines we are instrumenting and insert the
     * instrumentation.
     */
    bool varInfoAllocated = false;
    VarInfo *vi = NULL;
    for(FuncProto *fp: funcProto)
    {

	RTN rtn = RTN_FindByName(img, fp->name.c_str());

	if (RTN_Valid(rtn))
	{
	    /* If we found a routine we care about, allocate the
	     * VarInfo structure for that image. Init it if we can.
	     * If not, make it NULL.
	     */
	    if(!varInfoAllocated)
	    {
		varInfoAllocated = true;

		vi = new VarInfo();

		if (!vi->init(IMG_Name(img)))
		{
		    cerr<<"Failed to initialize VarInfo for image " << IMG_Name(img) << endl;
		    delete vi;
		    vi = NULL;
		}
	    }

	    FuncRecord *fr;
	    cout << "Procedure " << fp->name << " located." << endl;

	    PIN_GetLock(&lock, PIN_ThreadId() + 1);
	    if((fr = findFuncRecord(&funcRecords, fp->name)) == NULL)
	    {
		fr = allocateAndAdd(&funcRecords, fp, vi);
	    }


	    assert(fr != NULL);
	    
	    PIN_ReleaseLock(&lock);

	    RTN_Open(rtn);

	    // Instrument 
	    if(fp->number >= 0 && fp->size >= 0  && fp->retaddr >= 0)
	    {
		RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)callBeforeAlloc,
			       IARG_PTR, fr, IARG_THREAD_ID, IARG_RETURN_IP, 
			       IARG_FUNCARG_ENTRYPOINT_VALUE, fp->number, 
			       IARG_FUNCARG_ENTRYPOINT_VALUE, fp->size,
			       IARG_FUNCARG_ENTRYPOINT_VALUE, fp->retaddr, IARG_END);
	    }
	    else if(fp->number == -1 && fp->size >= 0 && fp->retaddr >= 0)
	    {
		RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)callBeforeAlloc,
			       IARG_PTR, fr, IARG_THREAD_ID, IARG_RETURN_IP, 
			       IARG_ADDRINT, 1, 
			       IARG_FUNCARG_ENTRYPOINT_VALUE, fp->size,
			       IARG_FUNCARG_ENTRYPOINT_VALUE, fp->retaddr, IARG_END);
	    }
	    else if(fp->number == -1 && fp->size >= 0 && fp->retaddr == -1)
	    {
		RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)callBeforeAlloc,
			       IARG_PTR, fr, IARG_THREAD_ID, IARG_RETURN_IP, 
			       IARG_ADDRINT, 1, 
			       IARG_FUNCARG_ENTRYPOINT_VALUE, fp->size,
			       IARG_UINT32, 0, IARG_END);
	    }
	    else if(fp->number >= 0 && fp->size >= 0  && fp->retaddr == -1)
	    {
		RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)callBeforeAlloc,
			       IARG_PTR, fr, IARG_THREAD_ID, IARG_RETURN_IP, 
			       IARG_FUNCARG_ENTRYPOINT_VALUE, fp->number, 
			       IARG_FUNCARG_ENTRYPOINT_VALUE, fp->size,
			       IARG_UINT32, 0, IARG_END);
	    }
	    else {
		cerr << "I did not understand this function prototype: " << endl
		     << fp->name << ": number " << fp->number << ", size " << fp->size
		     << ", retaddr " << fp->retaddr << endl;
		Usage();
		exit(-1);
	    }


	    RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR)callAfterAlloc,
			   IARG_PTR, fr, IARG_THREAD_ID, IARG_FUNCRET_EXITPOINT_VALUE, 
			   IARG_END);

	    RTN_Close(rtn);

	}
    }   
}
Пример #12
0
void
MMO_Generator_::_variables ()
{
  stringstream buffer;
  VarSymbolTable vt = _model->varTable ();
  vt->setPrintEnvironment (VST_INIT);
  if (_model->annotation ()->solver () == ANT_DASSL
      || _model->annotation ()->solver () == ANT_DOPRI)
    {
      vt->setPrintEnvironment (VST_CLASSIC_INIT);
    }
  string indent = _writer->indent (1);
  list<VarInfo>::iterator it;
  list<VarInfo> parameters = vt->parameters ();
  for (it = parameters.begin (); it != parameters.end (); it++)
    {
      VarInfo vi = *it;
      Index idx = vi->index ();
      stringstream reverse;
      if (vi->type ()->getType () == TYREAL)
	{
	  buffer << "double " << vt->print (vi);
	}
      else if (vi->type ()->getType () == TYINTEGER)
	{
	  buffer << "int " << vt->print (vi);
	  reverse << "int __reverse" << vt->print (vi);
	}
      if (vi->isArray ())
	{
	  buffer << "[" << vi->size () << "]";
	  reverse << "[" << vi->size () << "]";
	}
      else
	{
	  buffer << " = 0";
	  reverse << " = 0";
	}
      buffer << ";";
      if (vi->type ()->getType () == TYINTEGER)
	{
	  reverse << ";";
	  _writer->write (&reverse, WR_GLOBAL_VARS);
	}
      _writer->write (&buffer, WR_GLOBAL_VARS);
      if (vi->hasAssignment () || vi->hasStartModifier ()
	  || vi->hasEachModifier ())
	{
	  buffer << _model->printInitialAssignment (vi, indent);
	  _writer->write (&buffer, WR_START_CODE);
	}
    }
  _writer->newLine (WR_GLOBAL_VARS);
}