/*
 *  Fix OP function calls and inject debug names
 */
void OPSource::fixOpStructs(SgNode *n)
{
  SgInitializedName* initname = isSgInitializedName(n);
  if(initname)
  {
    string var_name = initname->get_name().getString();
    SgConstructorInitializer *initer = isSgConstructorInitializer(initname->get_initializer());
    if(initer)
    {
      string class_name = initer->get_class_decl()->get_name().getString();
      if(class_name.find("op_dat") != string::npos
          || class_name.find("op_dat_gbl") != string::npos
          || class_name.compare("_op_ptr") == 0 
          || class_name.compare("_op_set") == 0 
          || class_name.compare("_op_dat_const") == 0)
      {
        cout << "---Injecting Debug Name: " << var_name << "---" << endl;
        SgExprListExp* list = initer->get_args();
        SgExpressionPtrList &exprs = list->get_expressions();
        if( isSgStringVal(exprs.back()) == NULL )
        {
          list->append_expression(buildStringVal(var_name));
        }
      }
    }
  }
}
void BasicProgmemTransform::transformCharArrayInitialization(SgFunctionDeclaration *func) {
	/* *
	 * Translates statements of the form:
	 * char arr[n] = "some string"; to:
	 * char arr[n];
	 * strcpy_P(arr, <progmem placeholder>);
	 * */
	Rose_STL_Container<SgNode *> initNames = NodeQuery::querySubTree(func, V_SgInitializedName);
	for(auto &item: initNames) {
		SgInitializedName *initName = isSgInitializedName(item);
		if(initName->get_initializer() == NULL) {
			continue;
		}
		SgVariableDeclaration * varDecl = isSgVariableDeclaration(initName->get_declaration());
		if(varDecl == NULL) {
			continue;
		}
		SgAssignInitializer *assignInit = isSgAssignInitializer(initName->get_initializer());
		if(assignInit == NULL) {
			continue;
		}
		SgType *type = initName->get_type();
		SgType *eleType = SageInterface::getElementType(type);
		if(isSgArrayType(type) && eleType != NULL && isSgTypeChar(eleType)) {
			SgStringVal* strVal = isSgStringVal(assignInit->get_operand());
			std::string str = strVal->get_value();
			int arrSize = getDeclaredArraySize(isSgArrayType(type));
			if(arrSize == 0) {
				//char arr[] = "something";
				int size = str.length() + 1;
				SgArrayType *type = SageBuilder::buildArrayType(SageBuilder::buildCharType(), SageBuilder::buildIntVal(size));
				initName->set_type(type);
			}
			varDecl->reset_initializer(NULL);
			SgVariableDeclaration *placeholder = getVariableDeclPlaceholderForString(str);
			SgVarRefExp *ref = SageBuilder::buildVarRefExp(placeholder);
			std::stringstream instr;
			instr << "\n strcpy_P(" << initName->get_name().getString();
			instr <<  ", " << ref->get_symbol()->get_name().getString() << ");\n";
			SageInterface::attachComment(varDecl, instr.str(), PreprocessingInfo::after);
			printf("transformed %s\n", initName->unparseToString().c_str());
		}

	}
}
void BasicProgmemTransform::convertVarDeclToProgmemDecl(SgVariableDeclaration *varDecl) {
	printf("converting %s\n", varDecl->unparseToString().c_str());
	std::string dec = "const char ";
	SgInitializedName *initName = varDecl->get_variables()[0];
	std::string literal = isSgAssignInitializer(initName->get_initializer())->get_operand()->unparseToString();
	dec += initName->get_name().getString() + "[] PROGMEM =" + literal + ";";
	insertPreprocessingInfo(dec);
	SageInterface::removeStatement(varDecl, true);
}
Exemplo n.º 4
0
    virtual void visit(SgNode* n) {
        if (isSgBasicBlock(n)) {
            SgBasicBlock* bb = isSgBasicBlock(n);
            SgStatementPtrList& stmts = bb->get_statements();
            size_t initi;
            for (size_t decli = 0; decli < stmts.size(); ++decli) {
                if (isSgVariableDeclaration(stmts[decli])) {
                    SgVariableDeclaration* decl = isSgVariableDeclaration(stmts[decli]);
                    SgInitializedNamePtrList& vars = decl->get_variables();
                    for (size_t vari = 0; vari != vars.size(); ++vari) {
                        SgInitializedName* in = vars[vari];
                        if (in->get_initializer() == 0) {
                            bool used = false;
                            for (initi = decli + 1; initi < stmts.size();
                                    used |= containsVariableReference(stmts[initi], in),
                                    ++initi) {
                                SgExprStatement* initExprStmt = isSgExprStatement(stmts[initi]);
                                if (initExprStmt) {
                                    SgExpression* top = initExprStmt->get_expression();
                                    if (isSgAssignOp(top)) {
                                        SgVarRefExp* vr = isSgVarRefExp(isSgAssignOp(top)->get_lhs_operand());
                                        ROSE_ASSERT(isSgAssignOp(top) != NULL);
                                        SgExpression* newinit = isSgAssignOp(top)->get_rhs_operand();
                                        if (!used && vr && vr->get_symbol()->get_declaration() == in) {
                                            ROSE_ASSERT(newinit != NULL);
                                            // printf ("MoveDeclarationsToFirstUseVisitor::visit(): newinit = %p = %s \n",newinit,newinit->class_name().c_str());
                                            ROSE_ASSERT(newinit->get_type() != NULL);
                                            SgAssignInitializer* i = new SgAssignInitializer(SgNULL_FILE,newinit,newinit->get_type());
                                            i->set_endOfConstruct(SgNULL_FILE);
                                            // printf ("Built a SgAssignInitializer #1 \n");
                                            vars[vari]->set_initializer(i);
                                            stmts[initi] = decl;
                                            newinit->set_parent(i);

                                            // DQ (6/23/2006): Set the parent and file_info pointers
                                            // printf ("Setting parent of i = %p = %s to parent = %p = %s \n",i,i->class_name().c_str(),in,in->class_name().c_str());
                                            i->set_parent(in);
                                            ROSE_ASSERT(i->get_parent() != NULL);

                                            i->set_file_info(new Sg_File_Info(*(newinit->get_file_info())));
                                            ROSE_ASSERT(i->get_file_info() != NULL);

                                            // Assumes only one var per declaration FIXME
                                            ROSE_ASSERT (vars.size() == 1);
                                            stmts.erase(stmts.begin() + decli);
                                            --decli; // To counteract ++decli in loop header
                                            break; // To get out of initi loop
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
int main(int argc, char** argv) {
	SgProject* proj = frontend(argc,argv);
	SgFunctionDeclaration* mainDecl = SageInterface::findMain(proj);
	SgFunctionDefinition* mainDef = mainDecl->get_definition();
	std::vector<SgNode*> ifExps;
	ifExps = NodeQuery::querySubTree(mainDef, V_SgIfStmt);
	for (int i = 0; i < ifExps.size(); i++) {
		getIfConds(isSgIfStmt(ifExps[i]), isSgScopeStatement(mainDef));
	}
	
	std::vector<SgNode*> assignNodes = NodeQuery::querySubTree(mainDef, V_SgVariableDeclaration);
	std::cout << assignNodes.size() << " nodes found" << std::endl;
	std::vector<SgBinaryOp*> bin_ops;
	std::vector<SgUnaryOp*> un_ops;
	std::vector<SgNode*> other;
	std::vector<SgExpression*> results;
	for (std::vector<SgNode*>::iterator i = assignNodes.begin(); i != assignNodes.end(); i++) {
	
		SgVariableDeclaration* vdecl = isSgVariableDeclaration(*i);
		SgInitializedNamePtrList vlst = vdecl->get_variables();
		SgInitializedName* initName = isSgInitializedName((*(vlst.begin())));
		SgExpression* exp = isSgAssignInitializer(initName->get_initializer())->get_operand();
		std::cout << exp->class_name() << std::endl;
		if (!isSgFunctionCallExp(exp)) {
			getExps(exp, isSgInitializedName(*i), results, 0);
		
	
	std::cout << "prefixes" << std::endl;
	for (int j = 0; j < prefixes.size(); j++) {
	        SgExprStatement* expSt = SageBuilder::buildExprStatement_nfi(prefixes[j]);
		SageInterface::insertStatement(isSgVariableDeclaration(*i),expSt,true);
		
		std::cout << prefixes[j]->class_name() << std::endl;
	}
	std::cout << "results" << std::endl;
	for (int j = 0; j < results.size(); j++) {
		std::cout << results[j]->class_name() << std::endl;
	}
	std::cout << "postfixes" << std::endl;
	for (int j = 0; j < postfixes.size(); j++) {
		SgExprStatement* expSt = SageBuilder::buildExprStatement_nfi(postfixes[j]);
                SageInterface::insertStatement(isSgVariableDeclaration(*i),expSt,false);
		std::cout << postfixes[j]->class_name() << std::endl;
	}
	
	replaceExps(exp,vdecl);
	simplifyExps(exp);
	}
		
	}
			
	backend(proj);
	return 0;
}
Exemplo n.º 6
0
    virtual void visit(SgNode* n) {
        if (isSgVarRefExp(n)) {
            SgVarRefExp* copy_vr = isSgVarRefExp(n);
            assert (copy_vr->get_symbol());
            SgInitializedName* copy = copy_vr->get_symbol()->get_declaration();
            assert (copy);
            if (!SageInterface::isReferenceType(copy->get_type()))
                return; // Fail if non-reference

            SgInitializer* copyinit = copy->get_initializer();
            SgNode* copyscope_ =
                copy->get_parent()->get_parent();
            while (!isSgScopeStatement(copyscope_))
                copyscope_ = copyscope_->get_parent();
            // cout << "copyscope is a " << copyscope_->sage_class_name() << endl;
            // SgScopeStatement* copyscope = isSgScopeStatement(copyscope_);
            if (isSgAssignInitializer(copyinit)) {
                SgAssignInitializer* init = isSgAssignInitializer(copyinit);
                SgExpression* orig_expr = init->get_operand();
                // cout << "orig is " << orig_expr->unparseToString() << ", copy is " << copy->get_name().str() << endl;
                bool shouldReplace = false;
                if (isSgVarRefExp(orig_expr)) {
                    SgVarRefExp* orig_vr = isSgVarRefExp(orig_expr);
                    // cout << "Found potential copy from " << orig_vr->get_symbol()->get_name().str() << " to " << copy_vr->get_symbol()->get_name().str() << endl;
                    SgInitializedName* orig = orig_vr->get_symbol()->get_declaration();
                    assert (orig);
                    SgNode* origscope = orig->get_parent()->get_parent();
                    assert (origscope);
                    shouldReplace = true;
                }
                if (shouldReplace) {
                    assert (orig_expr);
                    SgExpression* orig_copy =
                        isSgExpression(orig_expr /*->copy(SgTreeCopy()) */);
                    assert (orig_copy);
                    orig_copy->set_parent(copy_vr->get_parent());
                    isSgExpression(copy_vr->get_parent())->
                    replace_expression(copy_vr, orig_copy);
                }
            }
        }
    }
SgVariableDeclaration *BasicProgmemTransform::getVariableDeclPlaceholderForString(const std::string& str) {
	for(auto &varDecl: varDeclsToShift) {
		SgInitializedName *initName = varDecl->get_variables().at(0);
		SgAssignInitializer *assign = isSgAssignInitializer(initName->get_initializer());
		if(assign == NULL) {
			continue;
		}
		SgStringVal* strVal = isSgStringVal(assign->get_operand());
		if(strVal->get_value() == str) {
			return varDecl;
		}
	}
	if(additionalProgmemStrings.find(str) != additionalProgmemStrings.end()) {
		return additionalProgmemStrings[str];
	}
	std::string placeholder = sla->getStringLiteralLabel(str);
	SgType *type = SageBuilder::buildPointerType(SageBuilder::buildConstType(SageBuilder::buildCharType()));
	SgAssignInitializer *initializer = SageBuilder::buildAssignInitializer(SageBuilder::buildStringVal(str));
	SgGlobal *global = SageInterface::getFirstGlobalScope(project);
	SgVariableDeclaration *varDec = SageBuilder::buildVariableDeclaration( "ar" +placeholder, type, initializer, global);
	additionalProgmemStrings[str] = varDec;
	return varDec;
}
Exemplo n.º 8
0
DeterminismState getExpectation(SgNode *ast, const char *varName)
{
  SgName name(varName);

  Rose_STL_Container<SgNode*> sdNodes = NodeQuery::querySubTree(ast, &name, NodeQuery::VariableDeclarationFromName);
  if (sdNodes.size() != 1) {
    cerr << "Didn't find target variable " << varName << " in list of size " << sdNodes.size() << endl;

    for (Rose_STL_Container<SgNode*>::iterator i = sdNodes.begin(); i != sdNodes.end(); ++i)
      cerr << "\t" << (*(isSgVariableDeclaration(*i)->get_variables().begin()))->get_name().str() << endl;

    return QUESTIONABLE;
  }

  SgNode *nSd = *(sdNodes.begin());
  SgVariableDeclaration *vdSd = dynamic_cast<SgVariableDeclaration *>(nSd);
  if (!vdSd) {
    cerr << "Node wasn't a variable declaration" << endl;
    return QUESTIONABLE;
  }

  SgInitializedName *inSd = vdSd->get_decl_item(name);
  SgAssignInitializer *aiSd = dynamic_cast<SgAssignInitializer*>(inSd->get_initializer());
  if (!aiSd) {
    cerr << "Couldn't pull an assignment initializer out" << endl;
    return QUESTIONABLE;
  }

  SgIntVal *ivSd = dynamic_cast<SgIntVal*>(aiSd->get_operand());
  if (!ivSd) {
    cerr << "Assignment wasn't an intval" << endl;
    return QUESTIONABLE;
  }

  int value = ivSd->get_value();
  return value ? DETERMINISTIC : NONDETERMINISTIC;
}
Exemplo n.º 9
0
POETCode* POETAstInterface::Ast2POET(const Ast& n)
{
  static SgTemplateInstantiationFunctionDecl* tmp=0;
  SgNode* input = (SgNode*) n;
  if (input == 0) return EMPTY;
  POETCode* res = POETAstInterface::find_Ast2POET(input);
  if (res != 0) return res;

  {
  SgProject* sageProject=isSgProject(input); 
  if (sageProject != 0) {
    int filenum = sageProject->numberOfFiles(); 
    for (int i = 0; i < filenum; ++i) { 
      SgSourceFile* sageFile = isSgSourceFile(sageProject->get_fileList()[i]); 
      SgGlobal *root = sageFile->get_globalScope(); 
      SgDeclarationStatementPtrList declList = root->get_declarations ();
      POETCode* curfile = ROSE_2_POET_list(declList, 0, tmp);
      curfile = new POETCode_ext(sageFile, curfile);
      POETAstInterface::set_Ast2POET(sageFile, curfile);
      res=LIST(curfile, res);
    }
    POETAstInterface::set_Ast2POET(sageProject,res); 
    return res;
  } }
  { 
  SgBasicBlock* block = isSgBasicBlock(input);
  if (block != 0) {
    res=ROSE_2_POET_list(block->get_statements(), res, tmp);
    POETAstInterface::set_Ast2POET(block, res); 
    return res;
  } }
  { 
  SgExprListExp* block = isSgExprListExp(input);
  if (block != 0) {
    res=ROSE_2_POET_list(block->get_expressions(), 0, tmp);
    POETAstInterface::set_Ast2POET(block, res); 
    return res;
  } }
 {
  SgForStatement *f = isSgForStatement(input);
  if (f != 0) {
      POETCode* init = ROSE_2_POET_list(f->get_for_init_stmt()->get_init_stmt(),0, tmp);
      POETCode* ctrl = new POETCode_ext(f, TUPLE3(init,Ast2POET(f->get_test_expr()), Ast2POET(f->get_increment())));
      res = CODE_ACC("Nest", PAIR(ctrl,Ast2POET(f->get_loop_body())));  
      POETAstInterface::set_Ast2POET(input, res); 
      return res;
  }
  }
  {
    SgVarRefExp * v = isSgVarRefExp(input);
    if (v != 0) {
       res = STRING(v->get_symbol()->get_name().str());
       POETAstInterface::set_Ast2POET(input, res); 
       return res;
    }
  }
  {
    SgMemberFunctionRefExp * v = isSgMemberFunctionRefExp(input);
    if (v != 0) {
       res = STRING(v->get_symbol()->get_name().str());
       POETAstInterface::set_Ast2POET(input, res); 
       return res;
    }
  }
  {
    SgIntVal * v = isSgIntVal(input);
    if (v != 0) {
       res = ICONST(v->get_value());
       POETAstInterface::set_Ast2POET(input, res); 
       return res;
    }
  }
  {
   SgInitializedName* var = isSgInitializedName(input);
   if (var != 0) {
     POETCode* name = STRING(var->get_name().str()); 
     POETCode* init = Ast2POET(var->get_initializer());
     res = new POETCode_ext(var, PAIR(name,init));
     POETAstInterface::set_Ast2POET(input, res); 
     return res;
   }
  }

/*
  {
  std::string fname;
  AstInterface::AstList params;
  AstNodeType returnType;
  AstNodePtr body;
  if (AstInterface :: IsFunctionDefinition( input, &fname, &params, (AstInterface::AstList*)0, &body, (AstInterface::AstTypeList*)0, &returnType)) {
if (body != AST_NULL)
 std::cerr << "body not empty:" << fname << "\n";
      POETCode* c = TUPLE4(STRING(fname), ROSE_2_POET_list(0,params,0), 
                 STRING(AstInterface::GetTypeName(returnType)), 
                 Ast2POET(body.get_ptr()));
      res = new POETCode_ext(input, c);
      POETAstInterface::set_Ast2POET(input,res);
      return res;
  } }   
*/

  AstInterface::AstList c = AstInterface::GetChildrenList(input);
  switch (input->variantT()) {
    case V_SgCastExp:
    case V_SgAssignInitializer:
      res = Ast2POET(c[0]); 
      POETAstInterface::set_Ast2POET(input, res); return res; 
    case V_SgDotExp:
     {
      POETCode* v1 = Ast2POET(c[1]);
      if (dynamic_cast<POETString*>(v1)->get_content() == "operator()") 
           return Ast2POET(c[0]);
      res = CODE_ACC("Bop",TUPLE3(STRING("."), Ast2POET(c[0]), v1)); return res;
     }
    case V_SgLessThanOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("<"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgSubtractOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("-"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgAddOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("+"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgMultiplyOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("*"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgDivideOp:
      res = CODE_ACC("Bop",TUPLE3(STRING("/"),Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgAssignOp:
      res = CODE_ACC("Assign",PAIR(Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
    case V_SgFunctionCallExp:
      res = CODE_ACC("FunctionCall",PAIR(Ast2POET(c[0]), Ast2POET(c[1])));
      POETAstInterface::set_Ast2POET(input, res); return res;
  } 
  POETCode * c2 = 0; 
  if (tmp == 0) tmp=isSgTemplateInstantiationFunctionDecl(input);
   switch (c.size()) {
   case 0: break;
   case 1: c2 = Ast2POET(c[0]); break;
   case 2: c2 = PAIR(Ast2POET(c[0]),Ast2POET(c[1])); break;
   case 3: c2 = TUPLE3(Ast2POET(c[0]),Ast2POET(c[1]),Ast2POET(c[2])); break;
   case 4: c2 = TUPLE4(Ast2POET(c[0]),Ast2POET(c[1]),Ast2POET(c[2]),Ast2POET(c[3])); break;
   default: 
     //std::cerr << "too many children: " << c.size() << ":" << input->unparseToString() << "\n";
     c2 = EMPTY;
   }
  if (tmp == input) tmp = 0;
  res = new POETCode_ext(input, c2); 
  POETAstInterface::set_Ast2POET(input,res);
  return res;
}
Exemplo n.º 10
0
void runAnalyses(SgProject* root, Labeler* labeler, VariableIdMapping* variableIdMapping) {

  SPRAY::DFAnalysisBase::normalizeProgram(root);

  if(option_fi_constanalysis) {
    VarConstSetMap varConstSetMap;
    FIConstAnalysis fiConstAnalysis(variableIdMapping);
    fiConstAnalysis.runAnalysis(root);
    fiConstAnalysis.attachAstAttributes(labeler,"const-analysis-inout"); // not iolabeler
    if(csvConstResultFileName) {
      cout<<"INFO: generating const CSV file "<<option_prefix+csvConstResultFileName<<endl;
      fiConstAnalysis.writeCvsConstResult(*variableIdMapping, option_prefix+csvConstResultFileName);
    }
    cout << "INFO: annotating analysis results as comments."<<endl;
    AstAnnotator ara(labeler);
    ara.annotateAstAttributesAsCommentsBeforeStatements(root, "const-analysis-inout");
    ara.annotateAstAttributesAsCommentsAfterStatements(root, "const-analysis-inout");
  }

  if(option_at_analysis) {
    cout<<"STATUS: running address taken analysis."<<endl;
    cout << "STATUS: computing variable and function mappings."<<endl;
    // compute variableId mappings
    VariableIdMapping variableIdMapping;
    variableIdMapping.computeVariableSymbolMapping(root);
    // Compute function id mappings:
    FunctionIdMapping functionIdMapping;
    functionIdMapping.computeFunctionSymbolMapping(root);

    if(option_trace) {
      std::cout << std::endl << "TRACE: Variable Id Mapping:" << std::endl;
      variableIdMapping.toStream(std::cout);
      std::cout << std::endl << "TRACE: Function Id Mapping:" << std::endl;
      functionIdMapping.toStream(std::cout);
    }

    cout << "STATUS: computing address taken sets."<<endl;
    SPRAY::FIPointerAnalysis fipa(&variableIdMapping, &functionIdMapping, root);
    fipa.initialize();
    fipa.run();

    //cout << "STATUS: computed address taken sets:"<<endl;
    //fipa.getFIPointerInfo()->printInfoSets();

    bool createCsv = false;
    ofstream addressTakenCsvFile;
    if(csvAddressTakenResultFileName) {
      std::string addressTakenCsvFileName = option_prefix;
      addressTakenCsvFileName += csvAddressTakenResultFileName;
      addressTakenCsvFile.open(addressTakenCsvFileName.c_str());
      createCsv = true;
    }

    cout << "INFO: annotating declarations of address taken variables and functions."<<endl;

    // Annotate declarations/definitions of variables from which the address was taken:
    VariableIdSet addressTakenVariableIds = fipa.getAddressTakenVariables();
    for(VariableIdSet::const_iterator idIter = addressTakenVariableIds.begin(); idIter != addressTakenVariableIds.end(); ++idIter) {
      // Determine the variable declaration/definition:
      SgLocatedNode* decl = variableIdMapping.getVariableDeclaration(*idIter);
      if(!decl) {
        // The current variable is presumably a function parameter: Try to get the initialized name:
        SgVariableSymbol* varSymbol = isSgVariableSymbol(variableIdMapping.getSymbol(*idIter));
        ROSE_ASSERT(varSymbol);
        SgInitializedName* paramDecl = isSgInitializedName(varSymbol->get_declaration());
        // We should not have a real variable declaration for the parameter:
        ROSE_ASSERT(isSgFunctionParameterList(paramDecl->get_declaration()));

        // Use the InitializedName:
        decl = paramDecl;
      }

      if(decl) {
        // Create the comment:
        ostringstream commentStream;
        commentStream << "/* Address of \"" << variableIdMapping.variableName(*idIter) << "\" is "
                      << "presumably taken.*/";

        // Annotate first declaration:
        insertComment(commentStream.str(), PreprocessingInfo::before, decl);
        // TODO: Annotate other declarations too!

        // Annotate definition if available (e.g. not available in case of parameter):
        if(SgDeclarationStatement* variableDeclaration = isSgDeclarationStatement(decl)) {
          if(SgDeclarationStatement* definingDeclaration = variableDeclaration->get_definingDeclaration()) {
            insertComment(commentStream.str(), PreprocessingInfo::before, definingDeclaration);
          }
        }

        if(createCsv) {
          // Write variable info to csv:
          addressTakenCsvFile << VariableId::idKindIndicator << ","
                              // The id of the variable (id codes are influenced by the used system headers
                              //  and are therefore not stable/portable):
                              << (option_csv_stable ? string("<unstable>") : int_to_string((*idIter).getIdCode())) << ","
                              // Name of the variable:
                              << variableIdMapping.variableName(*idIter) << ","

                              // TODO: Mangled scope and type are currently not stable/portable
                              //  (see comments in getScopeAsMangledStableString(...))
                              // Mangled type of the variable (non-mangled type may contain commas (e.g. "A<int,bool>"):
                              << (option_csv_stable ? string("<unstable>") : variableIdMapping.getType(*idIter)->get_mangled().getString()) << ","
                              // Mangled scope of the variable:
                              << (option_csv_stable ? string("<unstable>") : getScopeAsMangledStableString(decl)) << ","

                              // Is the address taken? (currently only address taken variables are output to csv)
                              << "1" << endl;
        }
      }
      else {
        cout << "ERROR: No declaration for " << variableIdMapping.uniqueShortVariableName(*idIter) << " available." << endl;
        ROSE_ASSERT(false);
      }
    }

    // Annotate declarations and definitions of functions from which the address was taken:
    FunctionIdSet addressTakenFunctionIds = fipa.getAddressTakenFunctions();
    for(FunctionIdSet::const_iterator idIter = addressTakenFunctionIds.begin(); idIter != addressTakenFunctionIds.end(); ++idIter) {

      if(SgFunctionDeclaration* decl = functionIdMapping.getFunctionDeclaration(*idIter)) {
        // Create the comment:
        ostringstream commentStream;
        commentStream << "/* Address of \"" << functionIdMapping.getFunctionNameFromFunctionId(*idIter) << "(...)\" is "
                      << "presumably taken.*/";

        // Annotate first declaration:
        insertComment(commentStream.str(), PreprocessingInfo::before, decl);
        // TODO: Annotate other declarations too!

        // Annotate definition if available:
        if(SgDeclarationStatement* definingDeclaration = decl->get_definingDeclaration()) {
          insertComment(commentStream.str(), PreprocessingInfo::before, definingDeclaration);
        }

        if(createCsv) {
          addressTakenCsvFile << FunctionId::idKindIndicator << ","
                              // The id of the function (id codes are influenced by the used system headers
                              //  and are therefore not stable/portable):
                              << (option_csv_stable ? string("<unstable>") : int_to_string((*idIter).getIdCode())) << ","
                              // Name of the function:
                              << functionIdMapping.getFunctionNameFromFunctionId(*idIter) << ","

                              // TODO: Mangled scope and type are currently not stable/portable
                              //  (see comments in getScopeAsMangledStableString(...))
                              // Mangled type of the function (non-mangled type may contain commas (e.g. "void (A<int,bool>)"):
                              << (option_csv_stable ? string("<unstable>") : functionIdMapping.getTypeFromFunctionId(*idIter)->get_mangled().getString()) << ","
                              // Mangled scope of the function:
                              << (option_csv_stable ? string("<unstable>") :getScopeAsMangledStableString(decl)) << ","

                              // Is the address taken? (currently only address taken functions are output to csv)
                              << "1" << endl;
        }
      }
      else {
        cout << "ERROR: No declaration for " << functionIdMapping.getUniqueShortNameFromFunctionId(*idIter) << " available." << endl;
        ROSE_ASSERT(false);
      }
    }

    if(createCsv) {
      addressTakenCsvFile.close();
    }

#if 0
    VariableIdSet vidset=fipa.getModByPointer();
    cout<<"mod-set: "<<SPRAY::VariableIdSetPrettyPrint::str(vidset,variableIdMapping)<<endl;
#endif
  }
  
  if(option_interval_analysis) {
    cout << "STATUS: creating interval analyzer."<<endl;
    SPRAY::IntervalAnalysis* intervalAnalyzer=new SPRAY::IntervalAnalysis();
    cout << "STATUS: initializing interval analyzer."<<endl;
    intervalAnalyzer->setNoTopologicalSort(option_no_topological_sort);
    intervalAnalyzer->initialize(root);
    cout << "STATUS: running pointer analysis."<<endl;
    ROSE_ASSERT(intervalAnalyzer->getVariableIdMapping());
    SPRAY::FIPointerAnalysis* fipa=new FIPointerAnalysis(intervalAnalyzer->getVariableIdMapping(), intervalAnalyzer->getFunctionIdMapping(), root);
    fipa->initialize();
    fipa->run();
    intervalAnalyzer->setPointerAnalysis(fipa);
    cout << "STATUS: initializing interval transfer functions."<<endl;
    intervalAnalyzer->initializeTransferFunctions();
    cout << "STATUS: initializing interval global variables."<<endl;
    intervalAnalyzer->initializeGlobalVariables(root);
      
    intervalAnalyzer->setSolverTrace(option_trace);
    std::string funtofind="main";
    RoseAst completeast(root);
    SgFunctionDefinition* startFunRoot=completeast.findFunctionByName(funtofind);
    intervalAnalyzer->determineExtremalLabels(startFunRoot);
    intervalAnalyzer->run();

#if 0
    intervalAnalyzer->attachInInfoToAst("iv-analysis-in");
    intervalAnalyzer->attachOutInfoToAst("iv-analysis-out");
    AstAnnotator ara(intervalAnalyzer->getLabeler(),intervalAnalyzer->getVariableIdMapping());
    ara.annotateAstAttributesAsCommentsBeforeStatements(root, "iv-analysis-in");
    ara.annotateAstAttributesAsCommentsAfterStatements(root, "iv-analysis-out");
#else
    AnalysisAstAnnotator ara(intervalAnalyzer->getLabeler(),intervalAnalyzer->getVariableIdMapping());
    ara.annotateAnalysisPrePostInfoAsComments(root,"iv-analysis",intervalAnalyzer);
#endif
    if(option_check_static_array_bounds) {
      checkStaticArrayBounds(root,intervalAnalyzer);
    }
    // schroder3 (2016-08-08): Generate csv-file that contains unreachable statements:
    if(csvDeadCodeUnreachableFileName) {
      // Generate file name and open file:
      std::string deadCodeCsvFileName = option_prefix;
      deadCodeCsvFileName += csvDeadCodeUnreachableFileName;
      ofstream deadCodeCsvFile;
      deadCodeCsvFile.open(deadCodeCsvFileName.c_str());
      // Iteratate over all CFG nodes/ labels:
      for(Flow::const_node_iterator i = intervalAnalyzer->getFlow()->nodes_begin(); i != intervalAnalyzer->getFlow()->nodes_end(); ++i) {
        const Label& label = *i;
        // Do not output a function call twice (only the function call label and not the function call return label):
        if(!intervalAnalyzer->getLabeler()->isFunctionCallReturnLabel(label)) {
          /*const*/ IntervalPropertyState& intervalsLattice = *static_cast<IntervalPropertyState*>(intervalAnalyzer->getPreInfo(label.getId()));
          if(intervalsLattice.isBot()) {
            // Unreachable statement found:
            const SgNode* correspondingNode = intervalAnalyzer->getLabeler()->getNode(label);
            ROSE_ASSERT(correspondingNode);
            // Do not output scope statements ({ }, ...)
            if(!isSgScopeStatement(correspondingNode)) {
              deadCodeCsvFile << correspondingNode->get_file_info()->get_line()
                              << "," << SPRAY::replace_string(correspondingNode->unparseToString(), ",", "/*comma*/")
                              << endl;
            }
          }
        }
      }
      deadCodeCsvFile.close();
    }

    delete fipa;
  }

  if(option_lv_analysis) {
    cout << "STATUS: creating LV analysis."<<endl;
    SPRAY::LVAnalysis* lvAnalysis=new SPRAY::LVAnalysis();
    cout << "STATUS: initializing LV analysis."<<endl;
    lvAnalysis->setBackwardAnalysis();
    lvAnalysis->setNoTopologicalSort(option_no_topological_sort);
    lvAnalysis->initialize(root);
    cout << "STATUS: running pointer analysis."<<endl;
    ROSE_ASSERT(lvAnalysis->getVariableIdMapping());
    SPRAY::FIPointerAnalysis* fipa = new FIPointerAnalysis(lvAnalysis->getVariableIdMapping(), lvAnalysis->getFunctionIdMapping(), root);
    fipa->initialize();
    fipa->run();
    lvAnalysis->setPointerAnalysis(fipa);
    cout << "STATUS: initializing LV transfer functions."<<endl;
    lvAnalysis->initializeTransferFunctions();
    cout << "STATUS: initializing LV global variables."<<endl;
    lvAnalysis->initializeGlobalVariables(root);
    std::string funtofind="main";
    RoseAst completeast(root);
    SgFunctionDefinition* startFunRoot=completeast.findFunctionByName(funtofind);
    cout << "generating icfg_backward.dot."<<endl;
    write_file("icfg_backward.dot", lvAnalysis->getFlow()->toDot(lvAnalysis->getLabeler()));

    lvAnalysis->determineExtremalLabels(startFunRoot);
    lvAnalysis->run();
    cout << "INFO: attaching LV-data to AST."<<endl;
#if 0
    lvAnalysis->attachInInfoToAst("lv-analysis-in");
    lvAnalysis->attachOutInfoToAst("lv-analysis-out");
    AstAnnotator ara(lvAnalysis->getLabeler(),lvAnalysis->getVariableIdMapping());
    ara.annotateAstAttributesAsCommentsBeforeStatements(root, "lv-analysis-in");
    ara.annotateAstAttributesAsCommentsAfterStatements(root, "lv-analysis-out");
#else
    AnalysisAstAnnotator ara(lvAnalysis->getLabeler(),lvAnalysis->getVariableIdMapping());
    ara.annotateAnalysisPrePostInfoAsComments(root,"lv-analysis",lvAnalysis);
#endif

    // schroder3 (2016-08-15): Generate csv-file that contains dead assignments/ initializations:
    if(csvDeadCodeDeadStoreFileName) {
      // Generate file name and open file:
      std::string deadCodeCsvFileName = option_prefix;
      deadCodeCsvFileName += csvDeadCodeDeadStoreFileName;
      ofstream deadCodeCsvFile;
      deadCodeCsvFile.open(deadCodeCsvFileName.c_str());
      if(option_trace) {
        cout << "TRACE: checking for dead stores." << endl;
      }
      // Iteratate over all CFG nodes/ labels:
      for(Flow::const_node_iterator labIter = lvAnalysis->getFlow()->nodes_begin(); labIter != lvAnalysis->getFlow()->nodes_end(); ++labIter) {
        const Label& label = *labIter;
        // Do not output a function call twice (only the function call return label and not the function call label):
        if(!lvAnalysis->getLabeler()->isFunctionCallLabel(label)) {
          /*const*/ SgNode* correspondingNode = lvAnalysis->getLabeler()->getNode(label);
          ROSE_ASSERT(correspondingNode);
          if(/*const*/ SgExprStatement* exprStmt = isSgExprStatement(correspondingNode)) {
            correspondingNode = exprStmt->get_expression();
          }
          /*const*/ SgNode* association = 0;
          // Check if the corresponding node is an assignment or an initialization:
          if(isSgAssignOp(correspondingNode)) {
            association = correspondingNode;
          }
          else if(SgVariableDeclaration* varDecl = isSgVariableDeclaration(correspondingNode)) {
            SgInitializedName* initName = SgNodeHelper::getInitializedNameOfVariableDeclaration(varDecl);
            ROSE_ASSERT(initName);
            // Check whether there is an initialization that can be eliminated (reference initialization can not be eliminated).
            if(!SgNodeHelper::isReferenceType(initName->get_type()) && initName->get_initializer()) {
              association = correspondingNode;
            }
          }

          if(association) {
            if(option_trace) {
              cout << endl << "association: " << association->unparseToString() << endl;
            }
            VariableIdSet assignedVars = AnalysisAbstractionLayer::defVariables(association, *lvAnalysis->getVariableIdMapping(), fipa);
            /*const*/ LVLattice& liveVarsLattice = *static_cast<LVLattice*>(lvAnalysis->getPreInfo(label.getId()));
            if(option_trace) {
              cout << "live: " << liveVarsLattice.toString(lvAnalysis->getVariableIdMapping()) << endl;
              cout << "assigned: " << endl;
            }
            bool minOneIsLive = false;
            for(VariableIdSet::const_iterator assignedVarIter = assignedVars.begin(); assignedVarIter != assignedVars.end(); ++assignedVarIter) {
              if(option_trace) {
                cout << (*assignedVarIter).toString(*lvAnalysis->getVariableIdMapping()) << endl;
              }
              if(liveVarsLattice.exists(*assignedVarIter)) {
                minOneIsLive = true;
                break;
              }
            }
            if(!minOneIsLive) {
              if(option_trace) {
                cout << "association is dead." << endl;
              }
              // assignment to only dead variables found:
              deadCodeCsvFile << correspondingNode->get_file_info()->get_line()
                              << "," << SPRAY::replace_string(correspondingNode->unparseToString(), ",", "/*comma*/")
                              << endl;
            }
          }
        }
      }
      deadCodeCsvFile.close();
    }
    delete lvAnalysis;
  }

  if(option_rd_analysis) {
      cout << "STATUS: creating RD analyzer."<<endl;
      SPRAY::RDAnalysis* rdAnalysis=new SPRAY::RDAnalysis();
      cout << "STATUS: initializing RD analyzer."<<endl;
      rdAnalysis->setNoTopologicalSort(option_no_topological_sort);
      rdAnalysis->initialize(root);
      cout << "STATUS: initializing RD transfer functions."<<endl;
      rdAnalysis->initializeTransferFunctions();
      cout << "STATUS: initializing RD global variables."<<endl;
      rdAnalysis->initializeGlobalVariables(root);
      
      cout << "generating icfg_forward.dot."<<endl;
      write_file("icfg_forward.dot", rdAnalysis->getFlow()->toDot(rdAnalysis->getLabeler()));
    
      std::string funtofind="main";
      RoseAst completeast(root);
      SgFunctionDefinition* startFunRoot=completeast.findFunctionByName(funtofind);
      rdAnalysis->determineExtremalLabels(startFunRoot);
      rdAnalysis->run();
    
      cout << "INFO: attaching RD-data to AST."<<endl;
      rdAnalysis->attachInInfoToAst("rd-analysis-in");
      rdAnalysis->attachOutInfoToAst("rd-analysis-out");
      //printAttributes<RDAstAttribute>(rdAnalysis->getLabeler(),rdAnalysis->getVariableIdMapping(),"rd-analysis-in");
      cout << "INFO: annotating analysis results as comments."<<endl;
      ROSE_ASSERT(rdAnalysis->getVariableIdMapping());
#if 0
      AstAnnotator ara(rdAnalysis->getLabeler(),rdAnalysis->getVariableIdMapping());
      ara.annotateAstAttributesAsCommentsBeforeStatements(root, "rd-analysis-in");
      ara.annotateAstAttributesAsCommentsAfterStatements(root, "rd-analysis-out");
#else
      AnalysisAstAnnotator ara(rdAnalysis->getLabeler(),rdAnalysis->getVariableIdMapping());
      ara.annotateAnalysisPrePostInfoAsComments(root,"rd-analysis",rdAnalysis);
#endif

#if 0
      cout << "INFO: substituting uses with rhs of defs."<<endl;
      substituteUsesWithAvailableExpRhsOfDef("ud-analysis", root, rdAnalysis->getLabeler(), rdAnalysis->getVariableIdMapping());
#endif
      if(option_ud_analysis) {
        ROSE_ASSERT(option_rd_analysis);
        cout << "INFO: generating and attaching UD-data to AST."<<endl;
        createUDAstAttributeFromRDAttribute(rdAnalysis->getLabeler(),"rd-analysis-in", "ud-analysis");
        Flow* flow=rdAnalysis->getFlow();
        cout<<"Flow label-set size: "<<flow->nodeLabels().size()<<endl;
        CFAnalysis* cfAnalyzer0=rdAnalysis->getCFAnalyzer();
        int red=cfAnalyzer0->reduceBlockBeginNodes(*flow);
        cout<<"INFO: eliminated "<<red<<" block-begin nodes in ICFG."<<endl;
        
#if 0
        cout << "INFO: computing program statistics."<<endl;
        ProgramStatistics ps(rdAnalysis->getVariableIdMapping(),
                             rdAnalysis->getLabeler(), 
                             rdAnalysis->getFlow(),
                             "ud-analysis");
        ps.computeStatistics();
        //ps.printStatistics();
        cout << "INFO: generating resource usage visualization."<<endl;
        ps.setGenerateWithSource(false);
        ps.generateResourceUsageICFGDotFile("resourceusageicfg.dot");
        flow->resetDotOptions();
#endif
        cout << "INFO: generating visualization data."<<endl;
        // generate ICFG visualization
        cout << "generating icfg.dot."<<endl;
        write_file("icfg.dot", flow->toDot(rdAnalysis->getLabeler()));
        
        //  cout << "INFO: generating control dependence graph."<<endl;
        //Flow cdg=rdAnalysis->getCFAnalyzer()->controlDependenceGraph(*flow);

        cout << "generating datadependencegraph.dot."<<endl;
        DataDependenceVisualizer ddvis0(rdAnalysis->getLabeler(),
                                        rdAnalysis->getVariableIdMapping(),
                                        "ud-analysis");
        //printAttributes<UDAstAttribute>(rdAnalysis->getLabeler(),rdAnalysis->getVariableIdMapping(),"ud-analysis");
        //ddvis._showSourceCode=false; // for large programs
        ddvis0.generateDefUseDotGraph(root,"datadependencegraph.dot");
        flow->resetDotOptions();
        
        cout << "generating icfgdatadependencegraph.dot."<<endl;
        DataDependenceVisualizer ddvis1(rdAnalysis->getLabeler(),
                                        rdAnalysis->getVariableIdMapping(),
                                        "ud-analysis");
        ddvis1.includeFlowGraphEdges(flow);
        ddvis1.generateDefUseDotGraph(root,"icfgdatadependencegraph.dot");
        flow->resetDotOptions();
        
        cout << "generating icfgdatadependencegraph_clustered.dot."<<endl;
        DataDependenceVisualizer ddvis2(rdAnalysis->getLabeler(),
                                        rdAnalysis->getVariableIdMapping(),
                                        "ud-analysis");
        ddvis2.generateDotFunctionClusters(root,rdAnalysis->getCFAnalyzer(),"icfgdatadependencegraph_clustered.dot",true);
        
        cout << "generating icfg_clustered.dot."<<endl;
        DataDependenceVisualizer ddvis3(rdAnalysis->getLabeler(),
                                        rdAnalysis->getVariableIdMapping(),
                                        "ud-analysis");
        ddvis3.generateDotFunctionClusters(root,rdAnalysis->getCFAnalyzer(),"icfg_clustered.dot",false);
        
      }
    }
}
Exemplo n.º 11
0
ExprSynAttr *examineVariableDeclaration(SgVariableDeclaration* decl, ostream &out) {
  SgInitializedNamePtrList& name_list = decl->get_variables();
  SgInitializedNamePtrList::const_iterator name_iter;
  ExprSynAttr *ret = NULL;
  ExprSynAttr *gc = NULL;
  ret = new ExprSynAttr();
  for (name_iter = name_list.begin(); 
       name_iter != name_list.end(); 
       name_iter++) {
    SgInitializedName* name = *name_iter;
    SgSymbol* symbol = name->get_symbol_from_symbol_table();
    SgType *type = symbol->get_type();
    int nr_stars = 0;
    stringstream ss1;
    
    while (isSgArrayType(type) ||
            isSgPointerType(type)) {
        if (isSgArrayType(type)) {
            SgArrayType *atype = isSgArrayType(type);
            SgExpression *expr = atype->get_index();

            type = atype->get_base_type();
            ss1 << "[";
            if (expr)
                examineExpr(expr, ss1);
            ss1 << "]";
        } else {
            SgPointerType *ttype = isSgPointerType(type);
            type = ttype->get_base_type();
            nr_stars++;
        }
    }

    examinePrimTypeName(type, ret->code);
    ret->code << " ";
    for (int i = 0; i < nr_stars; ++i)
        ret->code << "*";
    ret->code << symbol->get_name().getString();
    ret->code << ss1.str();

    ss1.str("");

    SgInitializer *initer = name->get_initializer();
    if (initer) {
        switch (initer->variantT()) {
            case V_SgAssignInitializer:
                SgAssignInitializer *ai = isSgAssignInitializer(initer);
                SgExpression *expr = ai->get_operand();
                if (expr) {
                    ret->code << "=";
                    gc = examineExpr(expr, ret->code);
                    if (gc != NULL)
                        delete gc;
                }
                break;
            default:
                break;
        }
    }

    /* end of this decl */
    ret->code << ";";
    out << ret->code.str();

    return ret;

    /*
    cout << "[Decl] Variable (name:"<<symbol->get_name().getString();
    cout << ",type:"<<symbol->get_type()->class_name();
    cout << ",init:";

    SgInitializer* init_expr = name->get_initializer();
    if (init_expr) 
      cout << init_expr->class_name();
    else
      cout << "none";
    cout << ")" << endl;
    */
  }
}
Exemplo n.º 12
0
bool
TaintAnalysis::transfer(const Function& func, const DataflowNode& node_, NodeState& state, const std::vector<Lattice*>& dfInfo) {
    static size_t ncalls = 0;
    if (debug) {
        *debug <<"TaintAnalysis::transfer-" <<++ncalls <<"(func=" <<func.get_name() <<",\n"
               <<"                        node={" <<StringUtility::makeOneLine(node_.toString()) <<"},\n"
               <<"                        state={" <<state.str(this, "                            ") <<",\n"
               <<"                        dfInfo[" <<dfInfo.size() <<"]={...})\n";
    }

    SgNode *node = node_.getNode();
    assert(!dfInfo.empty());
    FiniteVarsExprsProductLattice *prodLat = dynamic_cast<FiniteVarsExprsProductLattice*>(dfInfo.front());
    bool modified = magic_tainted(node, prodLat); // some values are automatically tainted based on their name

    // Process AST nodes that transfer taintedness.  Most of these operations have one or more inputs from which a result
    // is always calculated the same way.  So we just gather up the inputs and do the calculation at the very end of this
    // function.  The other operations are handled individually within their "if" bodies.
    TaintLattice *result = NULL;                    // result pointer into the taint lattice
    std::vector<TaintLattice*> inputs;              // input pointers into the taint lattice
    if (isSgAssignInitializer(node)) {
        // as in "int a = b"
        SgAssignInitializer *xop = isSgAssignInitializer(node);
        TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(SgExpr2Var(xop->get_operand())));
        inputs.push_back(in1);

    } else if (isSgAggregateInitializer(node)) {
        // as in "int a[1] = {b}"
        SgAggregateInitializer *xop = isSgAggregateInitializer(node);
        const SgExpressionPtrList &exprs = xop->get_initializers()->get_expressions();
        for (size_t i=0; i<exprs.size(); ++i) {
            varID in_id = SgExpr2Var(exprs[i]);
            TaintLattice *in = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in_id));
            inputs.push_back(in);
        }

    } else if (isSgInitializedName(node)) {
        SgInitializedName *xop = isSgInitializedName(node);
        if (xop->get_initializer()) {
            varID in1_id = SgExpr2Var(xop->get_initializer());
            TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id));
            inputs.push_back(in1);
        }

    } else if (isSgValueExp(node)) {
        // numeric and character constants
        SgValueExp *xop = isSgValueExp(node);
        result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(SgExpr2Var(xop)));
        if (result)
            modified = result->set_vertex(TaintLattice::VERTEX_UNTAINTED);
        
    } else if (isSgAddressOfOp(node)) {
        // as in "&x".  The result taintedness has nothing to do with the value in x.
        /*void*/

    } else if (isSgBinaryOp(node)) {
        // as in "a + b"
        SgBinaryOp *xop = isSgBinaryOp(node);
        varID in1_id = SgExpr2Var(isSgExpression(xop->get_lhs_operand()));
        TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id));
        inputs.push_back(in1);
        varID in2_id = SgExpr2Var(isSgExpression(xop->get_rhs_operand()));
        TaintLattice *in2 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in2_id));
        inputs.push_back(in2);

        if (isSgAssignOp(node)) { // copy the rhs lattice to the lhs lattice (as well as the entire '=' expression result)
            assert(in1 && in2);
            modified = in1->meetUpdate(in2);
        }

    } else if (isSgUnaryOp(node)) {
        // as in "-a"
        SgUnaryOp *xop = isSgUnaryOp(node);
        varID in1_id = SgExpr2Var(xop->get_operand());
        TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id));
        inputs.push_back(in1);

    } else if (isSgReturnStmt(node)) {
        // as in "return a".  The result will always be dead, so we're just doing this to get some debugging output.  Most
        // of our test inputs are functions, and the test examines the function's returned taintedness.
        SgReturnStmt *xop = isSgReturnStmt(node);
        varID in1_id = SgExpr2Var(xop->get_expression());
        TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id));
        inputs.push_back(in1);

    }


    // Update the result lattice (unless dead) with the inputs (unless dead) by using the meedUpdate() method.  All this
    // means is that the new result will be the maximum of the old result and all inputs, where "maximum" is defined such
    // that "tainted" is greater than "untainted" (and both of them are greater than bottom/unknown).
    for (size_t i=0; i<inputs.size(); ++i)
        if (debug)
            *debug <<"TaintAnalysis::transfer: input " <<(i+1) <<" is " <<lattice_info(inputs[i]) <<"\n";
    if (!result && varID::isValidVarExp(node)) {
        varID result_id(node); // NOTE: constructor doesn't handle all SgExpression nodes, thus the next "if"
        result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(result_id));
    }
    if (!result && isSgExpression(node)) {
        varID result_id = SgExpr2Var(isSgExpression(node));
        result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(result_id));
    }
    if (result) {
        for (size_t i=0; i<inputs.size(); ++i) {
            if (inputs[i])
                modified = result->meetUpdate(inputs[i]) || modified;
        }
    }
    if (debug)
        *debug <<"TaintAnalysis::transfer: result is " <<lattice_info(result) <<(modified?" (modified)":" (not modified)") <<"\n";

    return modified;
}
Exemplo n.º 13
0
    virtual void visit(SgNode* n) {
        if (isSgVarRefExp(n)) {
            SgVarRefExp* copy_vr = isSgVarRefExp(n);
            assert (copy_vr->get_symbol());
            SgInitializedName* copy = copy_vr->get_symbol()->get_declaration();
            assert (copy);
            SgInitializer* copyinit = copy->get_initializer();
            SgScopeStatement* copyscope =
                SageInterface::getScope(copy->get_parent()->get_parent());
            if (isSgAssignInitializer(copyinit)) {
                SgAssignInitializer* init =
                    isSgAssignInitializer(copyinit);
                SgExpression* orig_expr = init->get_operand();
                // cout << "orig is " << orig_expr->unparseToString() << ", copy is " << copy->get_name().str() << endl;
                if (!isPotentiallyModified(copy_vr, copyscope) &&
                        !isSgGlobal(copyscope) &&
                        !isSgNamespaceDefinitionStatement(copyscope)) {
                    bool shouldReplace = false;
                    if (isSgVarRefExp(orig_expr)) {
                        SgVarRefExp* orig_vr = isSgVarRefExp(orig_expr);
                        // cout << "Found potential copy from " << orig_vr->get_symbol()->get_name().str() << " to " << copy_vr->get_symbol()->get_name().str() << endl;
                        SgInitializedName* orig =
                            orig_vr->get_symbol()->get_declaration();
                        assert (orig);
                        SgNode* origscope = orig->get_parent()->get_parent();
                        assert (origscope);
                        if (!hasAddressTaken(orig_vr, origscope) &&
                                isSgBasicBlock(copyscope) &&
                                !isPotentiallyModifiedDuringLifeOf(isSgBasicBlock(copyscope),
                                        orig, copy) &&
                                !isSgGlobal(origscope) &&
                                !isSgNamespaceDefinitionStatement(origscope)) {
                            shouldReplace = true;
                        }
                    } else if (isSgValueExp(orig_expr)) {
                        shouldReplace = true;
                    }
                    // cout << "shouldReplace is " << shouldReplace << endl;
                    if (shouldReplace) {
                        assert (orig_expr);
                        SgExpression* orig_copy = isSgExpression(orig_expr /*->copy(SgTreeCopy()) */);
                        assert (orig_copy);
                        orig_copy->set_parent(copy_vr->get_parent());
                        orig_copy->set_lvalue(copy_vr->get_lvalue());

                        ROSE_ASSERT(copy_vr != NULL);
                        ROSE_ASSERT(copy_vr->get_parent() != NULL);
                        // ROSE_ASSERT(isSgExpression(copy_vr->get_parent()) != NULL);

                        // DQ (12/15/2006): Need to handle cases where the parent is a SgStatement or a SgExpression (or make it an error).
                        // isSgExpression(copy_vr->get_parent())->replace_expression(copy_vr, orig_copy);
                        SgStatement* statement = isSgStatement(copy_vr->get_parent());
                        if (statement != NULL)
                        {
                            statement->replace_expression(copy_vr, orig_copy);
                        }
                        else
                        {
                            SgExpression* expression = isSgExpression(copy_vr->get_parent());
                            if (expression != NULL)
                            {
                                expression->replace_expression(copy_vr, orig_copy);
                            }
                            else
                            {
                                printf ("Error: what is this copy_vr->get_parent() = %s \n",copy_vr->get_parent()->class_name().c_str());
                                ROSE_ASSERT(false);
                            }
                        }

                    }
                }
            }
        }
    }
Exemplo n.º 14
0
set<SgInitializedName*> computeLiveVars(SgStatement* stmt, const X86CTranslationPolicy& conv, map<SgLabelStatement*, set<SgInitializedName*> >& liveVarsForLabels, set<SgInitializedName*> currentLiveVars, bool actuallyRemove) {
  switch (stmt->variantT()) {
    case V_SgBasicBlock: {
      const SgStatementPtrList& stmts = isSgBasicBlock(stmt)->get_statements();
      for (size_t i = stmts.size(); i > 0; --i) {
        currentLiveVars = computeLiveVars(stmts[i - 1], conv, liveVarsForLabels, currentLiveVars, actuallyRemove);
      }
      return currentLiveVars;
    }
    case V_SgPragmaDeclaration: return currentLiveVars;
    case V_SgDefaultOptionStmt: return currentLiveVars;
    case V_SgCaseOptionStmt: {
      return computeLiveVars(isSgCaseOptionStmt(stmt)->get_body(), conv, liveVarsForLabels, currentLiveVars, actuallyRemove);
    }
    case V_SgLabelStatement: {
      liveVarsForLabels[isSgLabelStatement(stmt)] = currentLiveVars;
      return currentLiveVars;
    }
    case V_SgGotoStatement: {
      return liveVarsForLabels[isSgGotoStatement(stmt)->get_label()];
    }
    case V_SgSwitchStatement: {
      SgSwitchStatement* s = isSgSwitchStatement(stmt);
      SgBasicBlock* swBody = isSgBasicBlock(s->get_body());
      ROSE_ASSERT (swBody);
      const SgStatementPtrList& bodyStmts = swBody->get_statements();
      set<SgInitializedName*> liveForBody; // Assumes any statement in the body is possible
      for (size_t i = 0; i < bodyStmts.size(); ++i) {
        setUnionInplace(liveForBody, computeLiveVars(bodyStmts[i], conv, liveVarsForLabels, currentLiveVars, actuallyRemove));
      }
      return computeLiveVars(s->get_item_selector(), conv, liveVarsForLabels, liveForBody, actuallyRemove);
    }
    case V_SgContinueStmt: {
      return makeAllPossibleVars(conv);
    }
    case V_SgIfStmt: {
      set<SgInitializedName*> liveForBranches = computeLiveVars(isSgIfStmt(stmt)->get_true_body(), conv, liveVarsForLabels, currentLiveVars, actuallyRemove);
      setUnionInplace(liveForBranches, (isSgIfStmt(stmt)->get_false_body() != NULL ? computeLiveVars(isSgIfStmt(stmt)->get_false_body(), conv, liveVarsForLabels, currentLiveVars, actuallyRemove) : set<SgInitializedName*>()));
      return computeLiveVars(isSgIfStmt(stmt)->get_conditional(), conv, liveVarsForLabels, liveForBranches, actuallyRemove);
    }
    case V_SgWhileStmt: {
      while (true) {
        set<SgInitializedName*> liveVarsSave = currentLiveVars;
        currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_body(), conv, liveVarsForLabels, currentLiveVars, false);
        currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_condition(), conv, liveVarsForLabels, currentLiveVars, false);
        setUnionInplace(currentLiveVars, liveVarsSave);
        if (liveVarsSave == currentLiveVars) break;
      }
      if (actuallyRemove) {
        set<SgInitializedName*> liveVarsSave = currentLiveVars;
        currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_body(), conv, liveVarsForLabels, currentLiveVars, true);
        currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_condition(), conv, liveVarsForLabels, currentLiveVars, true);
        setUnionInplace(currentLiveVars, liveVarsSave);
      }
      return currentLiveVars;
    }
    case V_SgBreakStmt: return set<SgInitializedName*>();
    case V_SgExprStatement: {
      SgExpression* e = isSgExprStatement(stmt)->get_expression();
      switch (e->variantT()) {
        case V_SgAssignOp: {
          SgVarRefExp* lhs = isSgVarRefExp(isSgAssignOp(e)->get_lhs_operand());
          ROSE_ASSERT (lhs);
          SgInitializedName* in = lhs->get_symbol()->get_declaration();
          if (currentLiveVars.find(in) == currentLiveVars.end()) {
            if (actuallyRemove) {
              // cerr << "Removing assignment " << e->unparseToString() << endl;
              isSgStatement(stmt->get_parent())->remove_statement(stmt);
            }
            return currentLiveVars;
          } else {
            currentLiveVars.erase(in);
            getUsedVariables(isSgAssignOp(e)->get_rhs_operand(), currentLiveVars);
            return currentLiveVars;
          }
        }
        case V_SgFunctionCallExp: {
          getUsedVariables(e, currentLiveVars);
          SgFunctionRefExp* fr = isSgFunctionRefExp(isSgFunctionCallExp(e)->get_function());
          ROSE_ASSERT (fr);
          if (fr->get_symbol()->get_declaration() == conv.interruptSym->get_declaration()) {
            setUnionInplace(currentLiveVars, makeAllPossibleVars(conv));
            return currentLiveVars;
          } else {
            return currentLiveVars;
          }
        }
        default: {
          getUsedVariables(e, currentLiveVars);
          return currentLiveVars;
        }
      }
    }
    case V_SgVariableDeclaration: {
      ROSE_ASSERT (isSgVariableDeclaration(stmt)->get_variables().size() == 1);
      SgInitializedName* in = isSgVariableDeclaration(stmt)->get_variables()[0];
      bool isConst = isConstType(in->get_type());
      if (currentLiveVars.find(in) == currentLiveVars.end() && isConst) {
        if (actuallyRemove) {
          // cerr << "Removing decl " << stmt->unparseToString() << endl;
          isSgStatement(stmt->get_parent())->remove_statement(stmt);
        }
        return currentLiveVars;
      } else {
        currentLiveVars.erase(in);
        if (in->get_initializer()) {
          getUsedVariables(in->get_initializer(), currentLiveVars);
        }
        return currentLiveVars;
      }
    }
    default: cerr << "computeLiveVars: " << stmt->class_name() << endl; abort();
  }
}
// Convert something like "int a = foo();" into "int a; a = foo();"
SgAssignOp* convertInitializerIntoAssignment(SgAssignInitializer* init)
   {
#ifndef CXX_IS_ROSE_CODE_GENERATION
     using namespace SageBuilder;
     assert (SageInterface::isDefaultConstructible(init->get_operand_i()->get_type()));
     SgStatement* stmt = getStatementOfExpression(init);
     assert (stmt);
     SgScopeStatement* parent = isSgScopeStatement(stmt->get_parent());
     if (!parent && isSgForInitStatement(stmt->get_parent()))
          parent = isSgScopeStatement(stmt->get_parent()->get_parent()->get_parent());
     assert (parent);
     SgNode* initparent = init->get_parent();
     assert (initparent);

     SgInitializedName* initname = NULL;
     if (isSgInitializedName(initparent))
          initname = isSgInitializedName(initparent);
       else
          if (isSgVariableDefinition(initparent))
               initname = isSgVariableDefinition(initparent)->get_vardefn();
            else
               if (isSgVariableDeclaration(initparent))
                  {
                    SgInitializedNamePtrList& vars = isSgVariableDeclaration(initparent)->get_variables();
                    for (SgInitializedNamePtrList::iterator i = vars.begin(); i != vars.end(); ++i)
                       {
                         if ((*i)->get_initializer() == init)
                            {
                              initname = *i;
                              break;
                            }
                       }
                  }
                 else
                  {
                    std::cout << "initparent is a " << initparent->sage_class_name() << std::endl;
                    assert (!"Should not happen");
                  }

     assert (initname);
     assert (initname->get_initializer() == init);
     assert (parent);
     SgSymbol* sym = initname->get_symbol_from_symbol_table();
     ROSE_ASSERT (isSgVariableSymbol(sym));
     SgVarRefExp* vr = buildVarRefExp(isSgVariableSymbol(sym));
     vr->set_lvalue(true);
     SgExprStatement* assign_stmt = buildAssignStatement(vr, init->get_operand());

     initname->set_initializer(NULL);

  // assignment->set_parent(assign_stmt);
  // cout << "stmt is " << stmt->unparseToString() << endl;
  // cout << "stmt->get_parent() is a " << stmt->get_parent()->sage_class_name() << endl;

     myStatementInsert(stmt, assign_stmt, false);
     assign_stmt->set_parent(parent);

  // FixSgTree(assign_stmt);
  // FixSgTree(parent);

  // AstPostProcessing(assign_stmt);
     return isSgAssignOp(assign_stmt->get_expression());
#else
     return NULL;
#endif
   }
Exemplo n.º 16
0
//searches for locations where types may be connected through assignment, passing as argument and returns
//then passes the associated node along with the expression to link variables.
int Analysis::variableSetAnalysis(SgProject* project, SgType* matchType, bool base){
  RoseAst wholeAST(project);
  list<SgVariableDeclaration*> listOfGlobalVars = SgNodeHelper::listOfGlobalVars(project);
  if(listOfGlobalVars.size() > 0){
    for(auto varDec : listOfGlobalVars){
      SgInitializedName* initName = SgNodeHelper::getInitializedNameOfVariableDeclaration(varDec);
      if(!initName) continue;
      SgInitializer* init = initName->get_initializer();
      if(!init) continue;
      SgType* keyType = initName->get_type();
      if(!checkMatch(base, keyType, matchType)) continue;
      addToMap(varDec, varDec);  
      if(!isArrayPointerType(keyType)) continue;
      SgExpression* exp = init;
      linkVariables(varDec, keyType, exp);
    }
  }
  list<SgFunctionDefinition*> listOfFunctionDefinitions = SgNodeHelper::listOfFunctionDefinitions(project);
  for(auto funDef : listOfFunctionDefinitions){  
    SgInitializedNamePtrList& initNameList = SgNodeHelper::getFunctionDefinitionFormalParameterList(funDef);
    SgFunctionDeclaration* funDec = funDef->get_declaration();
    if(checkMatch(base, funDec->get_type()->get_return_type(), matchType)) addToMap(funDec, funDec);
    for(auto init : initNameList) if(checkMatch(base, init->get_type(), matchType)) addToMap(init, init);
    RoseAst ast(funDef);
    for(RoseAst::iterator i = ast.begin(); i!=ast.end(); i++){
      SgNode* key = nullptr;
      SgType* keyType = nullptr;
      SgExpression* exp = nullptr;
      if(SgAssignOp* assignOp = isSgAssignOp(*i)){
        SgExpression* lhs = assignOp->get_lhs_operand();
        if(SgVarRefExp* varRef = isSgVarRefExp(lhs)){
          keyType = varRef->get_type();
          if(!isArrayPointerType(keyType)) continue;    
          SgVariableSymbol* varSym = varRef->get_symbol();
	  key = varSym->get_declaration()->get_declaration();
        }
        exp = assignOp->get_rhs_operand();
      }
      else if(SgVariableDeclaration* varDec = isSgVariableDeclaration(*i)){
        SgInitializedName* initName = SgNodeHelper::getInitializedNameOfVariableDeclaration(varDec);
        if(!initName) continue;
        if(checkMatch(base, matchType, initName->get_type())) addToMap(varDec, varDec);
        SgInitializer* init = initName->get_initializer();
        if(!init) continue;
        keyType = initName->get_type();
        if(!isArrayPointerType(keyType)) continue;
        key = initName->get_declaration();
        exp = init;
      }
      else if(SgFunctionCallExp* callExp = isSgFunctionCallExp(*i)){
        SgFunctionDefinition* funDef = SgNodeHelper::determineFunctionDefinition(callExp);
        if(!funDef) continue;
        SgInitializedNamePtrList& initNameList = SgNodeHelper::getFunctionDefinitionFormalParameterList(funDef);
        SgExpressionPtrList& expList = callExp->get_args()->get_expressions();
        auto initIter = initNameList.begin();
        auto expIter  = expList.begin(); 
        while(initIter != initNameList.end()){
          if(isArrayPointerType((*initIter)->get_type())){
            if(checkMatch(base, matchType, (*initIter)->get_type())) linkVariables((*initIter), (*initIter)->get_type(), (*expIter));
          }
          ++initIter;
          ++expIter;
        }
      }
      else if(SgReturnStmt* ret = isSgReturnStmt(*i)){
        exp = ret->get_expression();
        keyType = exp->get_type();
        if(!isArrayPointerType(keyType)) continue;
        key = funDec;
         
      }
      if(!checkMatch(base, keyType, matchType)) continue;
      if(key && keyType && exp) linkVariables(key, keyType, exp);
    }
  }
  for(auto i = setMap.begin(); i != setMap.end(); ++i){
    bool intersect = false;
    set<SgNode*>* found = nullptr;
    for(auto j = listSets.begin(); j != listSets.end(); ++j){
      intersect = setIntersect(*j, i->second);
      if((*j)->count(i->first)) intersect = true;
      if(found != nullptr && intersect){ 
        inPlaceUnion(found, i->second);
        inPlaceUnion(found, *j);
        (found)->insert(i->first);
        j = listSets.erase(j);
        ++j;
      }
      else if(intersect){
        inPlaceUnion(*j, i->second);
        (*j)->insert(i->first);
        found = *j;
      }
    }
    if(!intersect){
      set<SgNode*>* copy = copySet(i->second);
      copy->insert(i->first);
      listSets.push_back(copy);
    }
  }
  return 0;
}
Exemplo n.º 17
0
Arquivo: Nodes.cpp Projeto: 8l/rose
ForLoop::ForLoop( SgForStatement * l ) 
: BasicNode(LOOPHEAD), myLoop(l), myLoopType(UNDEFINED), start(NULL), end(NULL),
body(NULL), back_edge(NULL), out(NULL), Iter(false)
{
	/* STEP 1 : Get initialization expression and symbol */
	SgStatementPtrList stmList = myLoop->get_init_stmt();
	if ( stmList.size() != 1 ) {
		report_error("Too many init statements",l);
	} else if ( isSgVariableDeclaration(stmList[0]) ) {
		
		SgInitializedNamePtrList initList = isSgVariableDeclaration(stmList[0])->get_variables();
		if ( initList.size() != 1 ) {
			report_error("To many induction variables",l);
		} else {
			SgInitializedName * initName = initList[0];
			if ( isSgAssignInitializer(initName->get_initializer()) ) {
				symbol = initName->get_name().getString();
				start = isSgAssignInitializer(initName->get_initializer())->get_operand();
			} else {
				report_error("Loop initializer is too complecated",initName);
			}
		}
		
	} else if ( isSgExprStatement(stmList[0]) ) {
		SgExpression * exp = isSgExprStatement(stmList[0])->get_expression();
		if ( isSgAssignOp(exp) ) {
			SgExpression * lhs = isSgAssignOp(exp)->get_lhs_operand();
			SgExpression * rhs = isSgAssignOp(exp)->get_rhs_operand();
			if ( isSgVarRefExp(lhs) ) {
				symbol = isSgVarRefExp(lhs)->get_symbol()->get_name().getString();
				start = rhs;
			} else {
				report_error("LHS of expression must be a single variable",exp);
			}
		} else {
			report_error("Init expression must be an Assign operation",exp);
		}
	} else {
		report_error("Loop initialization is not recognized",l);
	}
	
	/* STEP 2 : Get the test expression */
	SgExprStatement * expStm = isSgExprStatement(myLoop->get_test());
	if ( expStm ) {
		SgExpression * exp = expStm->get_expression();
		if ( isSgLessOrEqualOp(exp) ) {
			SgBinaryOp * binOp = isSgBinaryOp(exp);
			string name = isSgVarRefExp(isSgBinaryOp(exp)->get_lhs_operand())->get_symbol()->get_name().getString();
			
			if ( name != symbol )
				report_error("Loop init and test variable miss-match",exp);
			
			end = binOp->get_rhs_operand();
			
		} else if ( isSgLessThanOp(exp) ) {
			
			SgBinaryOp * binOp = isSgBinaryOp(exp);
			string name = isSgVarRefExp(binOp->get_lhs_operand())->get_symbol()->get_name().getString();
			
			if ( name != symbol )
				report_error("Loop init and test variable miss-match",exp);
			
			SgExpression * tempExp = SageInterface::copyExpression(binOp->get_rhs_operand());
			end = buildSubtractOp( tempExp, buildIntVal(1) );
			end->set_need_paren(true);
			tempExp = buildLessOrEqualOp( SageInterface::copyExpression(binOp->get_lhs_operand()), end );
			
			SageInterface::replaceExpression(exp, tempExp, false);
			
		} else {
			report_error("Test expression is not recognized. Re-write the loop or normilize it accordingly",exp);
		}
	} else {
		report_error("Test expression is not recognized. Sorry !", l);
	}
	
	/* STEP 3 : Check the stride */
	if ( !isSgPlusPlusOp(l->get_increment()) )
		report_error("Increment expression is not recognized. Re-write the loop or normilize it accordingly. Note: Only \"++\" operator supported.",l);
	
	/* STEP 4 : Link with Loop Tail node */
	back_edge = new ForLoop(start,end,symbol,l,this,this,LOOPTAIL);
	body = back_edge;
}
Exemplo n.º 18
0
int
main( int argc, char* argv[] )
   {
  // Initialize and check compatibility. See rose::initialize
     ROSE_INITIALIZE;

     SgProject* project = frontend(argc,argv);
     AstTests::runAllTests(project);

#if 0
  // Output the graph so that we can see the whole AST graph, for debugging.
     generateAstGraph(project, 4000);
#endif
#if 1
     printf ("Generate the dot output of the SAGE III AST \n");
     generateDOT ( *project );
     printf ("DONE: Generate the dot output of the SAGE III AST \n");
#endif

  // There are lots of way to write this, this is one simple approach; get all the function calls.
     std::vector<SgNode*> functionCalls = NodeQuery::querySubTree (project,V_SgFunctionCallExp);

  // Find the SgFunctionSymbol for snprintf so that we can reset references to "sprintf" to "snprintf" instead.
  // SgGlobal* globalScope = (*project)[0]->get_globalScope();
     SgSourceFile* sourceFile = isSgSourceFile(project->get_fileList()[0]);
     ROSE_ASSERT(sourceFile != NULL);
     SgGlobal* globalScope = sourceFile->get_globalScope();
     SgFunctionSymbol* snprintf_functionSymbol = globalScope->lookup_function_symbol("snprintf");
     ROSE_ASSERT(snprintf_functionSymbol != NULL);

  // Iterate over the function calls to find the calls to "sprintf"
     for (unsigned long i = 0; i < functionCalls.size(); i++)
        {
          SgFunctionCallExp* functionCallExp = isSgFunctionCallExp(functionCalls[i]);
          ROSE_ASSERT(functionCallExp != NULL);

          SgFunctionRefExp* functionRefExp = isSgFunctionRefExp(functionCallExp->get_function());
          if (functionRefExp != NULL)
             {
               SgFunctionSymbol* functionSymbol = functionRefExp->get_symbol();
               if (functionSymbol != NULL)
                  {
                    SgName functionName = functionSymbol->get_name();
                 // printf ("Function being called: %s \n",functionName.str());
                    if (functionName == "sprintf")
                       {
                      // Now we have something to do!
                         functionRefExp->set_symbol(snprintf_functionSymbol);

                      // Now add the "n" argument
                         SgExprListExp* functionArguments = functionCallExp->get_args();
                         SgExpressionPtrList & functionArgumentList = functionArguments->get_expressions();

                      // "sprintf" shuld have exactly 2 arguments (I guess the "..." don't count)
                         printf ("functionArgumentList.size() = %zu \n",functionArgumentList.size());
                      // ROSE_ASSERT(functionArgumentList.size() == 2);
                         SgExpressionPtrList::iterator i = functionArgumentList.begin();

                      // printf ("(*i) = %p = %s = %s \n",*i,(*i)->class_name().c_str(),SageInterface::get_name(*i).c_str());
                         SgVarRefExp* variableRefExp = isSgVarRefExp(*i);
                         ROSE_ASSERT(variableRefExp != NULL);

                      // printf ("variableRefExp->get_type() = %p = %s = %s \n",variableRefExp->get_type(),variableRefExp->get_type()->class_name().c_str(),SageInterface::get_name(variableRefExp->get_type()).c_str());

                         SgType* bufferType = variableRefExp->get_type();
                         SgExpression* bufferLengthExpression = NULL;
                         switch(bufferType->variantT())
                            {
                              case V_SgArrayType:
                                 {
                                   SgArrayType* arrayType = isSgArrayType(bufferType);
                                   bufferLengthExpression = arrayType->get_index();
                                   break;
                                 }

                              case V_SgPointerType:
                                 {
                                // SgPointerType* pointerType = isSgPointerType(bufferType);
                                   SgInitializedName* variableDeclaration = variableRefExp->get_symbol()->get_declaration();
                                   ROSE_ASSERT(variableDeclaration != NULL);
                                   SgExpression* initializer = variableDeclaration->get_initializer();
                                   if (initializer != NULL)
                                      {
                                        SgAssignInitializer* assignmentInitializer = isSgAssignInitializer(initializer);
                                        ROSE_ASSERT(assignmentInitializer != NULL);

                                     // This is the rhs of the initialization of the pointer (likely a malloc through a cast).
                                     // This assumes: buffer = (char*) malloc(bufferLengthExpression);
                                        SgExpression* initializationExpression = assignmentInitializer->get_operand();
                                        ROSE_ASSERT(initializationExpression != NULL);
                                        SgCastExp* castExp = isSgCastExp(initializationExpression);
                                        ROSE_ASSERT(castExp != NULL);
                                        SgFunctionCallExp* functionCall = isSgFunctionCallExp(castExp->get_operand());
                                        ROSE_ASSERT(functionCall != NULL);
                                        SgExprListExp* functionArguments = isSgExprListExp(functionCall->get_args());
                                        bufferLengthExpression = functionArguments->get_expressions()[0];
                                        ROSE_ASSERT(bufferLengthExpression != NULL);
                                      }
                                     else
                                      {
                                        printf ("Initializer not found, so no value for n in snprintf can be computed currently \n");
                                      }
                                   break;
                                 }

                              default:
                                 {
                                   printf ("Error: default reached in evaluation of buffer type = %p = %s \n",bufferType,bufferType->class_name().c_str());
                                   ROSE_ASSERT(false);
                                 }
                            }

                         ROSE_ASSERT(bufferLengthExpression != NULL);

                      // printf ("bufferLengthExpression = %p = %s = %s \n",bufferLengthExpression,bufferLengthExpression->class_name().c_str(),SageInterface::get_name(bufferLengthExpression).c_str());

                      // Jump over the first argument, the "n" is defined to be the 2nd argument (the rest are shifted one position).
                         i++;

                      // Build a deep copy of the expression used to define the static buffer (could be any complex expression).
                         SgTreeCopy copy_help;
                         SgExpression* bufferLengthExpression_copy = isSgExpression(bufferLengthExpression->copy(copy_help));

                      // Insert the "n" for the parameter list to work with "snprintf" instead of "sprintf"
                         functionArgumentList.insert(i,bufferLengthExpression_copy);
                       }
                  }
             }
        }

     return backend(project);
   }