void BasicProgmemTransform::transformFunction(SgFunctionDeclaration *func) {
	setupCharBufferForFunction(func);
	Rose_STL_Container<SgNode *> funcCalls = NodeQuery::querySubTree(func, V_SgFunctionCallExp);

	for(auto &funcCall: funcCalls) {
		int startPos = 0;
		SgFunctionCallExp *fcall = isSgFunctionCallExp(funcCall);
		Function callee(fcall);
		std::string orig = callee.get_name().getString();
		std::string replacement = getReplacementName(orig);
		bool arduinoP = isArduinoProgmemSafeFunction(callee);
		SgExpressionPtrList params = fcall->get_args()->get_expressions();
		param_pos_list progmemPositions = getPositionsToIgnore(orig);
		//TODO: figure out how to wrap with macro
//		for(auto &expr: params) {
		for(int index = 0; index < params.size(); index++){
			SgExpression *expr = params[index];
			SgVarRefExp* var = isSgVarRefExp(expr);
			if(var == NULL) { continue;}
			if(isVarDeclToRemove(var)) {
				if(arduinoP) {
					castProgmemParams(var);
				} else if(progmemPositions.find(index) == progmemPositions.end()) {
					loadProgmemStringsIntoBuffer(fcall, var, startPos);
				}
			}
		}
		if(replacement != "") {
			loadReplacewithProgmemFunction(fcall, replacement);
		}
	}
}
int BasicProgmemTransform::getBuffersizeNeededForFunction(SgFunctionDeclaration *func) {
	int maxSize = 0;
	Rose_STL_Container<SgNode *> funcCalls = NodeQuery::querySubTree(func, V_SgFunctionCallExp);
	for(auto &funcCall: funcCalls) {
		SgFunctionCallExp *fcall = isSgFunctionCallExp(funcCall);
		Function callee(fcall);
//		printf("function called: %s\n", callee.get_name().str());
		if(isArduinoProgmemSafeFunction(callee)) {
			continue;
		}
		param_pos_list ignoredPositions = getPositionsToIgnore(callee.get_name().getString());
		SgExpressionPtrList params = fcall->get_args()->get_expressions();
		int size = 0;
		for(int pos = 0; pos < params.size(); pos++) {
			if(ignoredPositions.find(pos) != ignoredPositions.end()) {
				continue;
			}
			SgVarRefExp* var = isSgVarRefExp(params[pos]);
			if(var) {
				SgInitializedName *initName = var->get_symbol()->get_declaration();
				if(isVarDeclToRemove(initName)) {
					SgExpression *rhs = getRHSOfVarDecl(initName);
					if(rhs && isSgStringVal(rhs)) {
						size += isSgStringVal(rhs)->get_value().size() + 1;
					}
				}
			}
		}
		if(size > maxSize) {
			maxSize = size;
		}
	}
	return maxSize;
}
// given a function call, sets argParamMap to map all simple arguments to this function to their 
// corresponding parameters
void FunctionState::setArgParamMap(SgFunctionCallExp* call, map<varID, varID>& argParamMap)
{
        Function func(call);
        
        SgExpressionPtrList args = call->get_args()->get_expressions();
        //SgInitializedNamePtrList params = funcArgToParamByRef(call);
        SgInitializedNamePtrList params = func.get_params();
        ROSE_ASSERT(args.size() == params.size());
        
        //cout << "setArgParamMap() #args="<<args.size()<<" #params="<<params.size()<<"\n";
        // the state of the callee's variables at the call site
        SgExpressionPtrList::iterator itA;
        SgInitializedNamePtrList::iterator itP;
        for(itA = args.begin(), itP = params.begin(); 
            itA!=args.end() && itP!=params.end(); 
            itA++, itP++)
        {
                //cout << "    itA="<<(*itA)->unparseToString()<<" itP="<<(*itP)->unparseToString()<<" isValid="<<varID::isValidVarExp(*itA)<<"\n";
                /*if(varID::isValidVarExp(*itA))
                {
                        varID arg(*itA);
                        varID param(*itP);
                        argParamMap[arg] = param;
                }*/
                varID arg = SgExpr2Var(*itA);
                varID param(*itP);
                argParamMap[arg] = param;
        }
}
Beispiel #4
0
//Generates SSA form numbers for the variables contained in *ex and attaches them as AstValueAttributes to the related SgNodes
//Assumption: *ex is located in in the inTrueBranch branch of the if node labeled *condLabel (These two arguments are required to generate the SSA form numbers)  
void SSAGenerator::processSgExpression(SgExpression* ex, Label* condLabel, bool inTrueBranch)
{
	SgIntVal* intVal = dynamic_cast<SgIntVal*>(ex);
	SgMinusOp* minusOp = dynamic_cast<SgMinusOp*>(ex);
	SgVarRefExp* varRef = dynamic_cast<SgVarRefExp*>(ex);
	SgBinaryOp* binOp = dynamic_cast<SgBinaryOp*>(ex);
	SgFunctionCallExp* funcCall = dynamic_cast<SgFunctionCallExp*>(ex);
	
	if(intVal) //Int value
	{
		//Nothing needs to be done; Case is listed here to have a collection of all expected cases
	}
	else if(minusOp)
	{
		processSgExpression(minusOp->get_operand(), condLabel, inTrueBranch);
	}
	else if(varRef) //Reference to variable that is NOT on the left hand side of an assignment
	{
		//Assign number to variable
		string varName = varRef->get_symbol()->get_name().getString();
		int varNumber = currentNumber(varName, condLabel, inTrueBranch);  
		logger[Sawyer::Message::DEBUG] << "Current number for variable " << varName << ": " << varNumber << endl;
		AstValueAttribute<int>* varNumberAtt = new AstValueAttribute<int>(varNumber);
		varRef->setAttribute("SSA_NUMBER", varNumberAtt);	
	}
	else if(binOp) //Binary operation
	{	
		SgExpression* lhs = binOp->get_lhs_operand();
		SgExpression* rhs = binOp->get_rhs_operand();

		//Process right hand side first
		processSgExpression(rhs, condLabel, inTrueBranch);
		
		//Process left hand side second
		SgAssignOp* assignOp = dynamic_cast<SgAssignOp*>(binOp);	
		if(assignOp) //Assignment to a variable
		{
			//Assign new number to that variable  
			SgVarRefExp* lhsVarRef = dynamic_cast<SgVarRefExp*>(lhs);
			assert(lhsVarRef != NULL);
			processAssignmentTo(lhsVarRef, condLabel, inTrueBranch);
		}
		else //Arithmetic operation or boolean operation (or something unexpected)
		{
			processSgExpression(lhs, condLabel, inTrueBranch);	
		}	
		
	}
	else if(funcCall) //Call to a function
			  //RERS specific; Only two function call types are supported: 
			  //(1) scanf("%d",&...); 
			  //(2) __VERIFIER_error(RERSVerifierErrorNumber); The artificial bool variable RERSErrorOccured has to be updated 
	{
		string funcName = funcCall->getAssociatedFunctionSymbol()->get_name().getString();
		logger[Sawyer::Message::DEBUG] << "Call to function: " << funcName << endl;
		if(funcName == "scanf") //(1)
		{
			SgExprListExp* funcArgs = funcCall->get_args();
			SgExpressionPtrList funcArgsPtrs = funcArgs->get_expressions();
			SgExpressionPtrList::iterator i = funcArgsPtrs.begin();
			while(i != funcArgsPtrs.end())
			{
				SgAddressOfOp* addrOp = dynamic_cast<SgAddressOfOp*>(*i);
				if(addrOp) 
				{
					SgVarRefExp* varRef = dynamic_cast<SgVarRefExp*>(addrOp->get_operand());
					if(varRef)
					{
						processAssignmentTo(varRef, condLabel, inTrueBranch);
					}
					else logger[Sawyer::Message::DEBUG] << "FOUND NO REFERENCE TO VARIABLE" << endl;
				}
				i++;	
			}	
		}
		else if(funcName == "__VERIFIER_error" && prepareReachabilityAnalysisZ3)
		{
			SgExprListExp* funcArgs = funcCall->get_args();
			SgExpressionPtrList funcArgsPtrs = funcArgs->get_expressions();
			assert(funcArgsPtrs.size() == 1);
			SgExpression* argument = *funcArgsPtrs.begin();
			SgIntVal* intArgument = dynamic_cast<SgIntVal*>(argument);
			assert(intArgument != NULL);
			if(intArgument->get_value() == RERSVerifierErrorNumber) //(2) 
			{
				int RERSErrorOccuredNumber = nextNumber("RERSErrorOccured", condLabel, inTrueBranch); 
				logger[Sawyer::Message::DEBUG] << "Next number for variable RERSErrorOccured: " << RERSErrorOccuredNumber << endl;
				AstValueAttribute<int>* numberAtt = new AstValueAttribute<int>(RERSErrorOccuredNumber);
				funcCall->setAttribute("SSA_NUMBER", numberAtt); 
			}
		}
		else logger[Sawyer::Message::DEBUG] << "Ignoring function call" << endl;
	}
	else //Unexpected
	{
		logger[Sawyer::Message::ERROR] << "ERROR: SgExpression could not be handled: " << ex->class_name() << endl;
		assert(false);
	}
}
Beispiel #5
0
void Fortran_to_C::translateArraySubscript(SgPntrArrRefExp* pntrArrRefExp)
{
  // get lhs operand
  SgVarRefExp*  arrayName = isSgVarRefExp(pntrArrRefExp->get_lhs_operand());
  SgExpression* baseExp = isSgExpression(arrayName);
  // get array symbol
  SgVariableSymbol* arraySymbol = arrayName->get_symbol();
  // get array type and dim_info
  SgArrayType* arrayType = isSgArrayType(arraySymbol->get_type());
  ROSE_ASSERT(arrayType);
  SgExprListExp* dimInfo = arrayType->get_dim_info();

  // get rhs operand
  SgExprListExp*  arraySubscript = isSgExprListExp(pntrArrRefExp->get_rhs_operand());
  if(arrayType->findBaseType()->variantT() == V_SgTypeString)
  {
    arraySubscript->prepend_expression(buildIntVal(1));
  }
  /*
    No matter it is single or multi dimensional array,  pntrArrRefExp always has a
    child, SgExprListExp, to store the subscript information.
  */
  if(arraySubscript != NULL)
  {
    // get the list of subscript
    SgExpressionPtrList subscriptExprList = arraySubscript->get_expressions();
    // get the list of dimension inforamtion from array definition.
    SgExpressionPtrList dimExpressionPtrList = dimInfo->get_expressions();

    // Create new SgExpressionPtrList for the linearalized array subscript. 
    SgExpressionPtrList newSubscriptExprList;

    // rank info has to match between subscripts and dim_info
    ROSE_ASSERT(arraySubscript->get_expressions().size() == dimInfo->get_expressions().size());

    if(subscriptExprList.size() == 1)
    {
      Rose_STL_Container<SgExpression*>::iterator j1 =  subscriptExprList.begin();
      Rose_STL_Container<SgExpression*>::iterator j2 =  dimExpressionPtrList.begin();
      SgExpression* newIndexExp = get0basedIndex(*j1, *j2);
      pntrArrRefExp->set_rhs_operand(newIndexExp);
    }
    else
    {
      Rose_STL_Container<SgExpression*>::reverse_iterator j1 =  subscriptExprList.rbegin();
      Rose_STL_Container<SgExpression*>::reverse_iterator j2 =  dimExpressionPtrList.rbegin();
      SgExpression* newIndexExp = get0basedIndex(*j1, *j2);
      SgPntrArrRefExp* newPntrArrRefExp = buildPntrArrRefExp(baseExp, newIndexExp);
      baseExp->set_parent(newPntrArrRefExp);
      j1 = j1 + 1;
      j2 = j2 + 1;
      for(; j1< (subscriptExprList.rend()-1); ++j1, ++j2)
      {
        SgExpression* newIndexExp = get0basedIndex(*j1, *j2);
        baseExp = isSgExpression(newPntrArrRefExp);
        newPntrArrRefExp = buildPntrArrRefExp(baseExp, newIndexExp);
        baseExp->set_parent(newPntrArrRefExp);
      }
      newIndexExp = get0basedIndex(*j1, *j2);
      pntrArrRefExp->set_lhs_operand(newPntrArrRefExp);
      pntrArrRefExp->set_rhs_operand(newIndexExp);
      newIndexExp->set_parent(pntrArrRefExp);
    }
  }
}
Beispiel #6
0
Datei: mlm.cpp Projekt: 8l/rose
void mlmTransform::transformCallExp(SgCallExpression* callExp)
{
    ROSE_ASSERT(callExp);
    SgFunctionRefExp* funcName = isSgFunctionRefExp(callExp->get_function());
    if(!funcName) 
      return;
    SgExprListExp* funcArgList = callExp->get_args();
    SgExpressionPtrList argList = funcArgList->get_expressions();
    SgScopeStatement* scope = getScope(callExp);         
    //cout << funcName->get_symbol()->get_name() << endl;

    /** if it is malloc, search for the mlm attribute and append the memory level **/
    if(strncmp("malloc",funcName->get_symbol()->get_name().str(),6) == 0)
    {
      if(argList.size() != 1)  return;
      SgExprListExp* funcArgList = callExp->get_args();

      // check if LHS of malloc has an attribute assigned
      SgNode* parentNode = callExp->get_parent();
      // parent node can be a casting expression
      if(isSgCastExp(parentNode))
      {
        parentNode = parentNode->get_parent();
      }
      // the mlm attribute
      AstAttribute* attr = NULL;
      // So far we spot two candidates for parentNode that we need to transform
      if(isSgAssignOp(parentNode))
      {
        SgAssignOp* assignOp = isSgAssignOp(parentNode);
        SgExpression* lhs = isSgExpression(assignOp->get_lhs_operand());
        if(!isSgVarRefExp(lhs))
        {
          //cout << "lhs:" << assignOp->get_lhs_operand()->class_name() << endl;

          // if pointer is packaged inside a struct, then we need to look down in lhs.
          if(isSgDotExp(lhs))
          {
            lhs = isSgDotExp(lhs)->get_rhs_operand();
          }
        }
        SgVarRefExp* lhsVarRef = isSgVarRefExp(lhs);
        ROSE_ASSERT(lhsVarRef);
        SgSymbol* symbol = lhsVarRef->get_symbol();
        ROSE_ASSERT(symbol);
        //retrieve the attribute from symbol
        attr = symbol->getAttribute("mlmAttribute");
        //cout << "LHS symbol name: " << symbol->get_name() << endl;
      }
      else if(isSgAssignInitializer(parentNode))
      {
        SgInitializedName* initName = isSgInitializedName(parentNode->get_parent());
        ROSE_ASSERT(initName);
        SgSymbol* symbol = initName->get_symbol_from_symbol_table();
        if(!symbol) return;
        ROSE_ASSERT(symbol);
        //retrieve the attribute from symbol
        attr = symbol->getAttribute("mlmAttribute");
        //cout << "Initialized symbol name: " << symbol->get_name() << endl;
      }
      else
      {
        // do nothing because no attribute assigned or we always set to default
      }
      // if there is a mlm attribute attached to the symbol, then create new malloc
      if(attr)
      {
        mlmAttribute* mlmAttr = dynamic_cast<mlmAttribute*> (attr);
        SgExprListExp* funcArgList = callExp->get_args();
        funcArgList->append_expression(buildIntVal(mlmAttr->getMemType()));
        replaceExpression(callExp, buildFunctionCallExp("mlm_malloc",deepCopy(callExp->get_type()),deepCopy(funcArgList),getScope(callExp)));
      }
    }
    else if(strncmp("memcpy",funcName->get_symbol()->get_name().str(),6) == 0)
    {
//      cout << "replacing memcpy" << endl;
      if(argList.size() != 3)  return;
      Rose_STL_Container<SgNode*> varList = NodeQuery::querySubTree(funcArgList, V_SgVarRefExp);
      SgVarRefExp* dst = isSgVarRefExp(varList[0]);
      SgVarRefExp* src = isSgVarRefExp(varList[1]);
      AstAttribute* attrDst = dst->get_symbol()->getAttribute("mlmAttribute");
      AstAttribute* attrSrc = src->get_symbol()->getAttribute("mlmAttribute");
      mlmAttribute* mlmAttrDst =  dynamic_cast<mlmAttribute*>(attrDst);
      mlmAttribute* mlmAttrSrc =  dynamic_cast<mlmAttribute*>(attrSrc);
//      if((mlmAttrDst && !mlmAttrSrc) || (mlmAttrDst && mlmAttrSrc && (mlmAttrDst->getMemType() < mlmAttrDst->getMemType())))
//      {
//        replaceExpression(callExp, buildFunctionCallExp("mlm_memcpy",deepCopy(callExp->get_type()),deepCopy(funcArgList),scope),true);
//        DeletepragmasList2.push_back(callExp);
//      }
//
//      else if((!mlmAttrDst && mlmAttrSrc) || (mlmAttrDst && mlmAttrSrc && (mlmAttrDst->getMemType() > mlmAttrDst->getMemType())))

// 09/30/14 Following Simon's suggestion, we always insert wait for the mlm_memcpy
//      {
         string tagName = generateUniqueVariableName(scope,"copy_tag");
         SgVariableDeclaration* newDecl = buildVariableDeclaration(tagName,
                                          buildOpaqueType("mlm_Tag",getGlobalScope(callExp)), 
                                          buildAssignInitializer(buildFunctionCallExp("mlm_memcpy",deepCopy(callExp->get_type()),deepCopy(funcArgList),scope)));
         SgExprStatement* waitStmt = buildFunctionCallStmt("mlm_waitComplete",
                                                           buildVoidType(),
                                                           buildExprListExp(buildVarRefExp(tagName,scope)),
                                                           scope); 
         insertStatement(getEnclosingStatement(callExp),newDecl,true);
         insertStatement(getEnclosingStatement(callExp),waitStmt,true);
         removeStatement(getEnclosingStatement(callExp));
//      }
    }
    else if(strncmp("free",funcName->get_symbol()->get_name().str(),4) == 0)
    {
//      cout << "replacing free" << endl;
      if(argList.size() != 1)  return;
      SgExpression* varExp = isSgExpression(argList[0]);
//cout << "exp:" << varExp->class_name() << endl;
      if(!isSgVarRefExp(varExp))
      {
        if(isSgCastExp(varExp))
        {
          varExp = isSgCastExp(varExp)->get_operand_i();
        }
        // if pointer is packaged inside a struct, then we need to look down in lhs.
        if(isSgDotExp(varExp))
        {
          varExp = isSgDotExp(varExp)->get_rhs_operand();
        }
      }
      SgVarRefExp* varRef = isSgVarRefExp(varExp);
      ROSE_ASSERT(varRef);
      AstAttribute* attr = varRef->get_symbol()->getAttribute("mlmAttribute");
      if(attr)
      {
        replaceExpression(callExp, buildFunctionCallExp("mlm_free",deepCopy(callExp->get_type()),deepCopy(funcArgList),scope),false);
      }
    }

}