Exemplo n.º 1
0
        aiRecord evaluateInheritedAttribute(SgNode* n, aiRecord inherited )
        {
                //aiRecord ir(inherited, n);
                aiRecord ir;
                SgPntrArrRefExp* arrRef;
                
                if((arrRef = isSgPntrArrRefExp(n)))
                {
                        ir.arrayNameSubtree = arrRef->get_lhs_operand();
                        ir.indexSubtree = arrRef->get_rhs_operand();
                        
                        // this SgPntrArrRefExp is the top-most isSgPntrArrRefExp if it is not the top of 
                        // the arrayNameSubtree of a higher-level SgPntrArrRefExp
                        ir.topArrayRefExpFlag = (n!=inherited.arrayNameSubtree);
                }
                
                // if this node is the top of the index subtree of an SgPntrArrRefExp, record this in ir
                if(inherited.indexSubtree == n)
                        ir.arrayIndexFlag = true;
                // otherwise, inherit from the parent node
                else
                        ir.arrayIndexFlag = inherited.arrayIndexFlag;
                
                arrIndexAttribute* aiAttr = new arrIndexAttribute(ir);
                n->addNewAttribute("ArrayIndex", aiAttr);
                
/*              if(isSgPntrArrRefExp(n))
                        printf("SgPntrArrRefExp:0x%x DOWN arrayIndexFlag=%d indexSubtree=0x%x\n", n, aiAttr->arrayIndexFlag, ir.indexSubtree);
                else
                        printf("SgNode:0x%x DOWN arrayIndexFlag=%d indexSubtree=0x%x\n", n, aiAttr->arrayIndexFlag, ir.indexSubtree);*/
                
                return ir;
        }
Exemplo n.º 2
0
void DataFlow<Annotation, Language, Runtime>::append_access(
  SgExpression * exp,
  std::vector<data_access_t> & access_set,
  const context_t & context
) const {
  std::vector<SgVarRefExp *> var_refs = SageInterface::querySubTree<SgVarRefExp>(exp);
  std::vector<SgVarRefExp *>::const_iterator it_var_ref;
  for (it_var_ref = var_refs.begin(); it_var_ref != var_refs.end(); it_var_ref++) {
    SgVarRefExp * var_ref = *it_var_ref;
    SgVariableSymbol * var_sym = var_ref->get_symbol();
    assert(var_sym != NULL);

    Data<Annotation> * data = NULL;
    typename std::set<Data<Annotation> *>::const_iterator it_data;
    for (it_data = context.datas.begin(); it_data != context.datas.end(); it_data++)
      if ((*it_data)->getVariableSymbol() == var_sym) {
        data = *it_data;
        break;
      }
    if (data == NULL)
      continue;

    access_set.push_back(data_access_t());
    access_set.back().data = data;
    SgPntrArrRefExp * parent = isSgPntrArrRefExp(var_ref->get_parent());
    while (parent != NULL) {
      access_set.back().subscripts.push_back(parent->get_rhs_operand_i());
      parent = isSgPntrArrRefExp(parent->get_parent());
    }
    assert(access_set.back().subscripts.size() == data->getSections().size());
  }
}
Exemplo n.º 3
0
bool MintArrayInterface::isArrayReference(SgExpression* ref, 
					  SgExpression** arrayName/*=NULL*/, 
					  vector<SgExpression*>* subscripts/*=NULL*/)
{
  SgExpression* arrayRef=NULL;

  if (ref->variantT() == V_SgPntrArrRefExp) {
    if (subscripts != 0 || arrayName != 0) {
      SgExpression* n = ref;
      while (true) {
	SgPntrArrRefExp *arr = isSgPntrArrRefExp(n);
	if (arr == 0)
	  break;
	n = arr->get_lhs_operand();
	// store left hand for possible reference exp to array variable                                                      
	if (arrayName!= 0)
	  arrayRef = n;
	// right hand stores subscripts                                                                                      
	if (subscripts != 0){
	  subscripts->push_back(arr->get_rhs_operand());
	  //cout << "sub: " << (arr->get_rhs_operand())->unparseToString() << endl;
	}
      } // end while                                       
      if  (arrayName !=NULL)
        {
          *arrayName = arrayRef;
        }
    }
    return true;
  }
  return false;
}
InheritedAttribute
BugSeeding::evaluateInheritedAttribute (
     SgNode* astNode,
     InheritedAttribute inheritedAttribute )
   {
  // Use this if we only want to seed bugs in loops
     bool isLoop = inheritedAttribute.isLoop           ||
                   (isSgForStatement(astNode) != NULL) ||
                   (isSgWhileStmt(astNode) != NULL)    ||
                   (isSgDoWhileStmt(astNode) != NULL);
  // Add Fortran support
     isLoop = isLoop || (isSgFortranDo(astNode) != NULL);

  // Mark future noes in this subtree as being part of a loop
     inheritedAttribute.isLoop = isLoop;

  // To test this on simple codes, optionally allow it to be applied everywhere
     bool applyEveryWhere = true;

     if (isLoop == true || applyEveryWhere == true)
        {
       // The inherited attribute is true iff we are inside a loop and this is a SgPntrArrRefExp.
          SgPntrArrRefExp *arrayReference = isSgPntrArrRefExp(astNode);
          if (arrayReference != NULL)
             {
            // Mark as a vulnerability
               inheritedAttribute.isVulnerability = true;

            // Now change the array index (to seed the buffer overflow bug)
               SgVarRefExp* arrayVarRef = isSgVarRefExp(arrayReference->get_lhs_operand());
               ROSE_ASSERT(arrayVarRef != NULL);
               ROSE_ASSERT(arrayVarRef->get_symbol() != NULL);
               SgInitializedName* arrayName = isSgInitializedName(arrayVarRef->get_symbol()->get_declaration());
               ROSE_ASSERT(arrayName != NULL);
               SgArrayType* arrayType = isSgArrayType(arrayName->get_type());
               ROSE_ASSERT(arrayType != NULL);
               SgExpression* arraySize = arrayType->get_index();

               SgTreeCopy copyHelp;
            // Make a copy of the expression used to hold the array size in the array declaration.
               SgExpression* arraySizeCopy = isSgExpression(arraySize->copy(copyHelp));
               ROSE_ASSERT(arraySizeCopy != NULL);

            // This is the existing index expression
               SgExpression* indexExpression = arrayReference->get_rhs_operand();
               ROSE_ASSERT(indexExpression != NULL);

            // Build a new expression: "array[n]" --> "array[n+arraySizeCopy]", where the arraySizeCopy is a size of "array"
               SgExpression* newIndexExpression = buildAddOp(indexExpression,arraySizeCopy);

            // Substitute the new expression for the old expression
               arrayReference->set_rhs_operand(newIndexExpression);
             }
        }

     return inheritedAttribute;
   }
void BasicProgmemTransform::transformArrayRef(SgFunctionDeclaration *func) {
	Rose_STL_Container<SgNode *> refs = NodeQuery::querySubTree(func, V_SgPntrArrRefExp);
	for(auto& item: refs) {
		SgPntrArrRefExp *exp = isSgPntrArrRefExp(item);
		SgVarRefExp *var = isSgVarRefExp(exp->get_lhs_operand());
		if(var == NULL) {
			continue;
		}
		if(isVarDeclToRemove(var)) {
			handleProgmemArrayIndexRef(exp);
		}
	}
}
Exemplo n.º 6
0
void ArrayAssignmentStatementTransformation::processArrayRefExp(SgVarRefExp* varRefExp, int dimension) {

	string variableName = varRefExp->get_symbol()->get_declaration()->get_name().str();
#if DEBUG
	cout << " Variable Name " << variableName << endl;
#endif

	SgScopeStatement* scope = getScope(varRefExp);
	//SgVarRefExp* replaceVarRefExp = buildVarRefExp(variableName, getScope(varRefExp));

	SgVarRefExp* newVarRefExp = buildVarRefExp("_" + variableName + "_pointer", scope);
	ROSE_ASSERT(newVarRefExp != NULL);

	string functionName = "SC_" + variableName;

	if (varRefExp->get_parent() != NULL) {
		SgFunctionCallExp* functionCallExpression = isSgFunctionCallExp(varRefExp->get_parent()->get_parent());
		if (functionCallExpression != NULL) {
			string operatorName = TransformationSupport::getFunctionName(functionCallExpression);

#if DEBUG
			cout << " Operator Name: " << operatorName << endl;
#endif

			if (operatorName == "operator()") {

				// Create a copy since the original might be deleted during replacement
				SgExprListExp* functionExprList = isSgExprListExp(copyExpression(functionCallExpression->get_args()));
				substituteIndexes(functionExprList, scope);
				SgFunctionCallExp* functionCallExp = buildFunctionCallExp(functionName, buildIntType(),
						functionExprList, scope);
				SgPntrArrRefExp* pntrArrRefExp = buildPntrArrRefExp(newVarRefExp, functionCallExp);
				cout << " PntrArrayReference replacement: " << pntrArrRefExp->unparseToString() << endl;
				replaceExpression(functionCallExpression, pntrArrRefExp, false);
			} else {

				SgPntrArrRefExp* pntrRefExp = buildArrayRefExp(newVarRefExp, dimension, functionName, scope);
				replaceExpression(varRefExp, pntrRefExp);
			}
		}
		else
		{
			// Added to support simple cases like A = A+B where there is dependence
			SgPntrArrRefExp* pntrRefExp = buildArrayRefExp(newVarRefExp, dimension, functionName, scope);
			replaceExpression(varRefExp, pntrRefExp);
		}
	}

}
Exemplo n.º 7
0
/*
 * This method inserts verify check for all the array references
 * present below the expr node.
 */
void fetchAndVerifyArrayRefs(SgExpression *expr,
		SgExprStatement *curExprStatement, bool isWrite) {

	vector<SgPntrArrRefExp*> arrayRefList = querySubTree<SgPntrArrRefExp> (
			expr, V_SgPntrArrRefExp);
	vector<SgPntrArrRefExp*> uniqueArrayRefList;

	// Create a new list as nodes change due to new statements
	for (vector<SgPntrArrRefExp*>::iterator iter = arrayRefList.begin(); iter
			!= arrayRefList.end(); iter++) {
		SgPntrArrRefExp *arrayRef = *iter;
		SgNode *parentArrayRef = arrayRef->get_parent();

		if (isSgPntrArrRefExp(parentArrayRef) == NULL)
			uniqueArrayRefList.push_back(arrayRef);
	}

	// Visit each array reference
	for (vector<SgPntrArrRefExp*>::iterator iter = uniqueArrayRefList.begin(); iter
			!= uniqueArrayRefList.end(); iter++) {
		insertChecksum(*iter, curExprStatement, isWrite);
	}
}
Exemplo n.º 8
0
        adRecord evaluateSynthesizedAttribute (SgNode* n, aiRecord inherited, 
                                               SubTreeSynthesizedAttributes synthesized )
        {
                //printf("evaluateSynthesizedAttribute(n=%p)\n");
                adRecord dr(n);
                SgPntrArrRefExp* arrRef;
                
                if((arrRef = isSgPntrArrRefExp(n)))
                {
                        //printf("evaluateSynthesizedAttribute() arrRef->lhs=%p, arrRef->rhs=%p\n", arrRef->get_lhs_operand(), );
                        bool found=false;
                        // look through both the synthesized attributes 
                        // (one from the SgPntrArrRefExp's array name subtree and one from the index subtree)
                        
                        // get the name subtree
                        for(SubTreeSynthesizedAttributes::iterator it=synthesized.begin(); it!=synthesized.end(); it++)
                        {
                                // if this synthesized attribute comes from SgPntrArrRefExp's array name subtree
                                // (there should be only one such subtree)
                                if((*it).origin == arrRef->get_lhs_operand())
                                {
                                        // copy over the info from the name subtree
                                        found = true;
                                        dr.arrayDim=(*it).arrayDim+1;
                                        // if the array name expression hasn't been found yet, this 
                                        // SgPntrArrRefExp's array name subtree must be it
                                        if((*it).arrayNameExp==NULL)
                                                dr.arrayNameExp = arrRef->get_lhs_operand();
                                        // otherwise, the real array name expression is deeper in the array name subtree, so just copy it over
                                        else
                                                dr.arrayNameExp = (*it).arrayNameExp;
                                        
                                        // initialize this SgPntrArrRefExp's list of indexes from the lower-level list
                                        dr.indexExprs = (*it).indexExprs;
//                                      break;
                                }
                        }
                        ROSE_ASSERT(found);
                        
                        found = false;
                        // get the index subtree
                        for(SubTreeSynthesizedAttributes::iterator it=synthesized.begin(); it!=synthesized.end(); it++)
                        {
                                // if this synthesized attribute comes from SgPntrArrRefExp's index subtree
                                // (there should be only one such subtree)
                                if((*it).origin == arrRef->get_rhs_operand())
                                {
                                        found = true;
                                        // add the current index expression to this SgPntrArrRefExp's list of indexes
                                        dr.indexExprs.push_front(isSgExpression((*it).origin));
                                }
                        }
                        ROSE_ASSERT(found);
                }
                
/*              if(isSgPntrArrRefExp(n))
                        printf("SgPntrArrRefExp:0x%x UP arrayIndexFlag=%d arrayNameExp=0x%x arrayDim=%d\n", n, dr.arrayIndexFlag, dr.arrayNameExp, dr.arrayDim);
                else
                        printf("SgNode:0x%x UP arrayIndexFlag=%d arrayNameExp=0x%x arrayDim=%d\n", n, dr.arrayIndexFlag, dr.arrayNameExp, dr.arrayDim);
                printf("         <%s>\n", n->unparseToString().c_str());*/
                                
                // label this node with its read/write access information
                arrIndexAttribute* aiAttr = new arrIndexAttribute(dr);
                char attrName[100];
                sprintf(attrName, "ArrayIndex: [%d, %d, %p, %d]", dr.arrayIndexFlag, dr.topArrayRefExpFlag, dr.arrayNameExp, dr.arrayDim);
                n->addNewAttribute(attrName, aiAttr);
                n->updateAttribute("ArrayIndex", aiAttr);
                
                return dr;
        }
Exemplo n.º 9
0
// Constructs _A_pointer[SC_A(_1,_2)]
SgPntrArrRefExp* buildAPPArrayRef(SgNode* astNode,
		ArrayAssignmentStatementQueryInheritedAttributeType & arrayAssignmentStatementQueryInheritedData,
		OperandDataBaseType & operandDataBase, SgScopeStatement* scope, SgExprListExp* parameterExpList) {
#if DEBUG
	printf("Contructing A++ array reference object \n");
#endif

	string returnString;

	SgVarRefExp* varRefExp = isSgVarRefExp(astNode);
	ROSE_ASSERT(varRefExp != NULL);
	SgVariableSymbol* variableSymbol = varRefExp->get_symbol();
	ROSE_ASSERT(variableSymbol != NULL);
	SgInitializedName* initializedName = variableSymbol->get_declaration();
	ROSE_ASSERT(initializedName != NULL);
	SgName variableName = initializedName->get_name();

	vector<SgExpression*> parameters;

	// Figure out the dimensionality of the statement globally
	int maxNumberOfIndexOffsets = 6; // default value for A++/P++ arrays
	ROSE_ASSERT(arrayAssignmentStatementQueryInheritedData.arrayStatementDimensionDefined == TRUE);
	if (arrayAssignmentStatementQueryInheritedData.arrayStatementDimensionDefined == TRUE) {
		// The the globally computed array dimension from the arrayAssignmentStatementQueryInheritedData
		maxNumberOfIndexOffsets = arrayAssignmentStatementQueryInheritedData.arrayStatementDimension;
	}

	// Then we want the minimum of all the dimensions accesses (or is it the maximum?)
	for (int n = 0; n < maxNumberOfIndexOffsets; n++) {
		parameters.push_back(buildVarRefExp("_" + StringUtility::numberToString(n + 1), scope));
	}

	// Make a reference to the global operand database
	//OperandDataBaseType & operandDataBase = accumulatorValue.operandDataBase;

	SgType* type = variableSymbol->get_type();
	ROSE_ASSERT(type != NULL);

	string typeName = TransformationSupport::getTypeName(type);
	ROSE_ASSERT(typeName.c_str() != NULL);

	// Copy the string from the SgName object to a string object
	string variableNameString = variableName.str();

	// Setup an intry in the synthesized attribute data base for this variable any
	// future results from analysis could be place there at this point as well
	// record the name in the synthesized attribute
	ROSE_ASSERT(operandDataBase.transformationOption > ArrayTransformationSupport::UnknownIndexingAccess);
	ArrayOperandDataBase arrayOperandDB = operandDataBase.setVariableName(variableNameString);

	// We could have specified in the inherited attribute that this array variable was
	// index and if so leave the value of $IDENTIFIER_STRING to be modified later in
	// the assembly of the operator() and if not do the string replacement on
	// $IDENTIFIER_STRING here (right now).

	returnString = string("$IDENTIFIER_STRING") + string("_pointer[SC") + string("$MACRO_NAME_SUBSTRING") + string("(")
			+ string("$OFFSET") + string(")]");

	string functionSuffix = "";
	SgPntrArrRefExp* pntrRefExp;

	cout << " arrayAssignmentStatementQueryInheritedData.getIsIndexedArrayOperand() "
			<< arrayAssignmentStatementQueryInheritedData.getIsIndexedArrayOperand() << endl;
	// The inherited attribute mechanism is not yet implimented
	if (arrayAssignmentStatementQueryInheritedData.getIsIndexedArrayOperand() == FALSE)
	//if(true)
	{
		// do the substitution of $OFFSET here since it our last chance
		// (offsetString is the list of index values "index1,index2,...,indexn")
		//returnString = StringUtility::copyEdit(returnString,"$OFFSET",offsetString);

		string operandIdentifier = arrayOperandDB.generateIdentifierString();
		// do the substitution of $IDENTIFIER_STRING here since it our last chance
		// if variable name is "A", generate: A_pointer[SC_A(index1,...)]
		// returnString = StringUtility::copyEdit (returnString,"$IDENTIFIER_STRING",variableNameString);
		ROSE_ASSERT(arrayOperandDB.indexingAccessCode > ArrayTransformationSupport::UnknownIndexingAccess);

		// Edit into place the name of the data pointer
		returnString = StringUtility::copyEdit(returnString, "$IDENTIFIER_STRING", operandIdentifier);

		// Optimize the case of uniform or unit indexing to generate a single subscript macro definition
		if ((arrayOperandDB.indexingAccessCode == ArrayTransformationSupport::UniformSizeUnitStride)
				|| (arrayOperandDB.indexingAccessCode == ArrayTransformationSupport::UniformSizeUniformStride))
			returnString = StringUtility::copyEdit(returnString, "$MACRO_NAME_SUBSTRING", "");
		else {
			returnString = StringUtility::copyEdit(returnString, "$MACRO_NAME_SUBSTRING", operandIdentifier);
			functionSuffix = operandIdentifier;
		}

		/* 
		 * Create SgPntrArrRefExp lhs is VarRefExp and rhs is SgFunctionCallExp
		 */
		SgVarRefExp* newVarRefExp = buildVarRefExp(operandIdentifier + "_pointer", scope);

		string functionName = "SC" + functionSuffix;

		SgFunctionCallExp* functionCallExp;
		if (parameterExpList == NULL)
			functionCallExp = buildFunctionCallExp(functionName, buildIntType(), buildExprListExp(parameters), scope);
		else
			functionCallExp = buildFunctionCallExp(functionName, buildIntType(), parameterExpList, scope);

		pntrRefExp = buildPntrArrRefExp(newVarRefExp, functionCallExp);

#if DEBUG
		cout << " pntrArrRefExp = " << pntrRefExp->unparseToString() << endl;
#endif 

	}

	return pntrRefExp;
}
Exemplo n.º 10
0
Arquivo: mlm.cpp Projeto: 8l/rose
/* This will allocate all the subdomain for every array
 * */
void mlmTransform::allocSubdomain(SgForStatement* loopNest, int tileSize)
{
    SgScopeStatement* scope = loopNest->get_scope();
    map<SgVariableSymbol*, SgPntrArrRefExp*> variableMap;
    std::vector<SgPntrArrRefExp* > pntrs= SageInterface::querySubTree<SgPntrArrRefExp>(loopNest,V_SgPntrArrRefExp);
    for(std::vector<SgPntrArrRefExp* >::iterator it = pntrs.begin(); it != pntrs.end(); ++ it)
    {
      vector<SgVariableSymbol*> tmp = SageInterface::getSymbolsUsedInExpression(*it);
      for(vector<SgVariableSymbol*>::iterator vit = tmp.begin(); vit != tmp.end(); ++vit)
      {
        //cout << "name = " << (*vit)->get_name()<< " type=" << (*vit)->get_type()->class_name() << endl;
        if(isSgArrayType((*vit)->get_type()) || isSgPointerType((*vit)->get_type()))
          variableMap[*vit] = *it;
      }
    }

    for(map<SgVariableSymbol*, SgPntrArrRefExp*>::iterator it=variableMap.begin(); it != variableMap.end(); ++it)
    {
  	string subArrayName = (*it).first->get_name().getString()+"_sub";
        cout << "name = " << (*it).first->get_name() << " new name:" << subArrayName << endl;
        SgType* subType = (*it).first->get_type();
        SgExpression* sizeExp;
        SgArrayType* oldtype;
        SgType* baseType;
        if(isSgArrayType((*it).first->get_type()))
        {
          // create the mutlti-dim data type for the subdomain
          oldtype = isSgArrayType((*it).first->get_type());
          std::vector<SgExpression*> arrayInfo = SageInterface::get_C_array_dimensions(oldtype);
          baseType = getArrayElementType(oldtype);
//cout << "dim size= " << getDimensionCount(oldtype) << " base type=" << baseType->class_name() << endl;
          for(int i=0; i <getDimensionCount(oldtype);++i)
          {
            SgArrayType* tmpArrayType;
            if(i == 0)
            {
              tmpArrayType = buildArrayType(baseType,buildIntVal(tileSize));
              sizeExp = buildIntVal(tileSize);
            }
            else
            {
              tmpArrayType = buildArrayType(baseType,buildIntVal(tileSize));
              sizeExp = buildMultiplyOp(sizeExp, buildIntVal(tileSize));
            }
            baseType = isSgType(tmpArrayType);
          }

          subType = buildPointerType(baseType);
        }
        // Building variable Declaration with malloc as initializer
        sizeExp = buildMultiplyOp(buildSizeOfOp(getArrayElementType(oldtype)),sizeExp);
        SgExprListExp* funcCallArgs = buildExprListExp(sizeExp);
        SgAssignInitializer* assignInit = buildAssignInitializer(buildFunctionCallExp("malloc",subType,funcCallArgs,scope));
  	SgVariableDeclaration* subArrayDecl = buildVariableDeclaration(subArrayName, subType,assignInit, scope);
        insertStatementBefore(loopNest, subArrayDecl);

        //Building memcpy function call
        //The offset, and size to be copied is still under development
        SgExprListExp* memcpyArgs = buildExprListExp(buildAddressOfOp(buildVarRefExp(subArrayName,scope)), buildAddressOfOp(buildVarRefExp((*it).first->get_name(),scope)), buildSizeOfOp(getArrayElementType(oldtype)));
        SgExprStatement* memcpyStmt = buildFunctionCallStmt("memcpy",buildVoidType(),memcpyArgs ,scope);
        insertStatementBefore(loopNest, memcpyStmt);
        
        SgPntrArrRefExp* pntrArrRef = (*it).second;
        pntrArrRef->set_lhs_operand(buildVarRefExp(subArrayName,scope)); 
    }
}
Exemplo n.º 11
0
std::string writeSgBinaryOpZ3(SgBinaryOp* op, SgExpression* lhs, SgExpression* rhs) {
	
	std::stringstream ss;
	std::string opStr;
	bool compAssign = false;
	if (isSgCompoundAssignOp(op)) {
		compAssign = true;
		opStr = getSgCompoundAssignOp(isSgCompoundAssignOp(op));
	
	}
	else {
		opStr = getSgBinaryOp(op);
	}
	ROSE_ASSERT(opStr != "unknown");
	std::string rhsstring;
	std::string lhsstring;
	lhsstring = getSgExpressionString(lhs);
	SgType* lhstyp;
	SgType* rhstyp;
	if (isSgArrayType(lhs->get_type())) {
	lhstyp = isSgArrayType(lhs->get_type())->get_base_type();	
	}
	else {
	lhstyp = lhs->get_type();
	}
	if (isSgArrayType(rhs->get_type())) {
	rhstyp = isSgArrayType(rhs->get_type())->get_base_type();
	}
	else {
	rhstyp = rhs->get_type();
	}
	if (isSgEnumType(lhs->get_type())) {
	}
	else {	
	ROSE_ASSERT(lhstyp == rhstyp);
	}	
	if (isSgValueExp(rhs)) {
		rhsstring = getSgValueExp(isSgValueExp(rhs));
	}
	else if (isSgUnaryOp(rhs)) {	
		rhsstring = getSgUnaryOp(isSgUnaryOp(rhs));
	}
		
	else {
		rhsstring = getSgExpressionString(rhs);
	}
	if (opStr == "/" && lhstyp->isIntegerType()) {
		opStr = "cdiv";
	} 
	if (opStr == "assign" || compAssign) {
		if (isSgVarRefExp(lhs)) {
		SgVarRefExp* lhsSgVarRefExp = isSgVarRefExp(lhs);
		int instances = SymbolToInstances[lhsSgVarRefExp->get_symbol()];
		std::stringstream instanceName;
		SymbolToInstances[lhsSgVarRefExp->get_symbol()] = instances + 1;
		std::string lhsname = SymbolToZ3[lhsSgVarRefExp->get_symbol()];
		instanceName << lhsname << "_" << (instances+1);
		SgType* varType = lhsSgVarRefExp->get_type();
		std::string typeZ3;
		if (varType->isFloatType()) {
			typeZ3 = "Real";
		}
		else if (varType->isIntegerType()) {
			typeZ3 = "Int";
		}
		else if (isSgEnumType(varType)) {
			typeZ3 = isSgEnumType(varType)->get_name().getString();
		}
		else {
			typeZ3 = "Unknown";
		}
		ss << "(declare-fun " << instanceName.str() << " () " << typeZ3 << ")\n";
		if (!compAssign) {  		
			ss << "(assert (= " << instanceName.str() << " " << rhsstring << "))";
		}
		else {
			std::stringstream oldInstanceName;
			oldInstanceName << lhsname << "_" << instances;
			ss << "(assert (= " << instanceName.str() << " (" << opStr << " " << oldInstanceName.str() << " " << rhsstring << ")))"; 
		}
		}
		
		else {
			ROSE_ASSERT(isSgPntrArrRefExp(lhs));
			std::string u_type;
			SgPntrArrRefExp* lhspntr = isSgPntrArrRefExp(lhs);
			SgVarRefExp* varlhspntr = isSgVarRefExp(lhspntr->get_lhs_operand());
			SgArrayType* arrTy = isSgArrayType(varlhspntr->get_type());
			if (arrTy->get_base_type()->isIntegerType()) {
				u_type = "Int";
			}
			else if (arrTy->get_base_type()->isFloatType()) {
				u_type = "Real";
			}
			else {
				std::cout << "unknown base type for array" << std::endl;
				ROSE_ASSERT(false);
			}
			std::stringstream oldInstanceName;
			SgVarRefExp* varexp = isSgVarRefExp((isSgPntrArrRefExp(lhs))->get_lhs_operand());
			oldInstanceName << SymbolToZ3[varexp->get_symbol()] << "_" << SymbolToInstances[varexp->get_symbol()];	
			int instances = SymbolToInstances[varexp->get_symbol()];
                	std::stringstream instanceName;
                	SymbolToInstances[varexp->get_symbol()] = instances + 1;
                	std::string lhsname = SymbolToZ3[varexp->get_symbol()];
                	instanceName << lhsname << "_" << instances+1;
			ss << "(declare-const " << instanceName.str() << " (Array Int " << u_type << "))\n ";	
			std::string indexstring = getSgExpressionString(isSgPntrArrRefExp(lhs)->get_rhs_operand());	
			ss << "(assert (= (store " << oldInstanceName.str() << " " << indexstring << " " << rhsstring << ") " << instanceName.str() << "))";
		}
	}	
	else if (opStr == "neq") {
	ss << "(not (= " << lhsstring << " " << rhsstring << "))";
	}
	else if (opStr == "or" || opStr == "and") {
		std::stringstream val_stream;	
		if (pathNodeTruthValue.find(op) != pathNodeTruthValue.end()) {
		bool logic_val = pathNodeTruthValue[op];
		//std::cout << ";and/or lhsstring " << lhsstring << "\n";
		//std::cout << ";and/or rhsstring " << rhsstring << "\n";
		if (opStr == "and") {
				
			if (logic_val) {
			
				std::string p_decl = "(assert (= " + lhsstring + " true))";
				declarations.push_back(p_decl);
				ss << rhsstring;
				//ss << "(and " << lhsstring << " " << rhsstring << ")";

			}
			else {
				std::string p_decl = "(assert (= " + lhsstring + " false))";
				declarations.push_back(p_decl);
				ss << "false";	
			}
		}
		else {
			if (logic_val) {
				std::string p_decl = "(assert (= " + lhsstring + " true))";
				declarations.push_back(p_decl);
				ss << "true"; 
			}
			else {
				std::string p_decl = "(assert (= " + lhsstring + " false))";
				declarations.push_back(p_decl);
				ss << rhsstring;
			}
		}
	}
	else {
		ss << "";
	}
	}
	else {	
	ss << "(" << opStr << " " << lhsstring << " " << rhsstring << ")";
	}
	return ss.str();
}