Example #1
0
void
CompassAnalyses::PreferFseekToRewind::Traversal::
visit(SgNode* node)
   { 
  // Implement your traversal here.  
     if(isSgFunctionCallExp(node))
     {
       SgFunctionCallExp* callSite = isSgFunctionCallExp(node);

       if(callSite->get_function() != NULL)
       {
         SgFunctionRefExp* functionRefExp = isSgFunctionRefExp(callSite->get_function());
         if(functionRefExp != NULL)
         {

           SgFunctionSymbol* functionSymbol = functionRefExp->get_symbol();
           ROSE_ASSERT(functionSymbol != NULL);

           std::string functionName = functionSymbol->get_name().getString();

           if(functionName == "rewind")
           {
             output->addOutput(new CheckerOutput(node));
           }
         }
       }
     }

   } //End of the visit function.
Example #2
0
void
CompassAnalyses::StringTokenToIntegerConverter::Traversal::
visit(SgNode* node)
   { 
  // Implement your traversal here.  
     if(isSgFunctionCallExp(node))
     {
       SgFunctionCallExp* callSite = isSgFunctionCallExp(node);

       if(callSite->get_function() != NULL)
       {
         SgFunctionRefExp* functionRefExp = isSgFunctionRefExp(callSite->get_function());
         if(functionRefExp != NULL)
         {
           SgFunctionSymbol* functionSymbol = functionRefExp->get_symbol();
           ROSE_ASSERT(functionSymbol != NULL);

           std::string functionName = functionSymbol->get_name().getString();

           if(functionName == "atoi" || functionName == "atol" || 
               functionName == "atoll" || functionName == "sscanf" )
           {
             output->addOutput(new CheckerOutput(node));
           }
         }
       }
     }

   } //End of the visit function.
Example #3
0
void SecureFunctionTypeTraversal::visit(SgNode* sgn)
{
    if(isSgFunctionCallExp(sgn)) {
        SgFunctionDeclaration* fndecl = isSgFunctionCallExp(sgn)->getAssociatedFunctionDeclaration();
        string filename = fndecl->get_file_info()->get_filename();
        if(filename != "compilerGenerated") {
            StringUtility::FileNameClassification classification;
            classification = StringUtility::classifyFileName(filename, this->sourcedir, this->trustedlibs);
            //StringUtility::FileNameLocation filetypeclassification = classification.getLocation();
            //cout << sgn->unparseToString() <<  filename << " : "  << classification.getLocation() << ", " <<  classification.getLibrary() << endl;
            bool isSecure;
            if(untrustedFunctions.find(fndecl->get_name().getString()) != untrustedFunctions.end()) {
                isSecure = false;
            }                 
                
            else if(classification.isLibraryCode() || classification.isUserCode()) {
                isSecure = true;
            }

            else {
                isSecure = false;
            }
            AstAttribute* attr = dynamic_cast<AstAttribute*> ( new SecureFunctionType(isSecure) );
            sgn->setAttribute("SECURE_TYPE", attr);            
        }
    }
}
Example #4
0
void ASLAnalysis::visit(SgNode* node){

   // concrete classes of AST nodes
   switch(node->variantT()){

      // naming scheme for variants: V_<classname>
      case V_SgFunctionDeclaration:{
         SgFunctionDeclaration* fdecl=isSgFunctionDeclaration(node);
      
         if(SgFunctionDefinition* fdef=fdecl->get_definition()) {
            std::string functionName=fdecl->get_name().getString();
            Sg_File_Info* ptrFileInfo=node->get_file_info();
            
            std::string aslPrefix="";
            if(ptrFileInfo){
               aslPrefix=ptrFileInfo->get_filenameString()+"/";
            }
            
            enterFunction(aslPrefix+functionName);  // set function name and reset enumeration counter
         }
      }
      break;
 
      // function calls through function pointers
      case V_SgPointerDerefExp:{
         if(isSgFunctionCallExp(node->get_parent()) && !(isSgFunctionCallExp(node->get_parent())->get_function() != node)){
#ifdef DEBUG
            std::cout<<"Function Pointer at call-site"<<std::endl;
#endif
            storeLocalSite(node);
            callSiteCounter++;
            functionPointerCallCounter++;
         }
      }
      break;
      
      case V_SgFunctionCallExp:{
         SgFunctionCallExp* fcall=isSgFunctionCallExp(node);
      
         if(SgFunctionRefExp* func=isSgFunctionRefExp(fcall->get_function())) {
            // SgFunctionSymbol* functionSymbol=func->get_symbol();
            // std::string functionName=functionSymbol->get_name().getString();
            callSiteCounter++;
         }
      }
      break;
      
   }
}
/*
 *  Fix op structure calls and inject debug names
 */
void OPSource::fixOpFunctions(SgNode *n)
{
  SgName var_name;
  SgFunctionCallExp *fn = isSgFunctionCallExp(n);
  if(fn != NULL)
  {
    string fn_name = fn->getAssociatedFunctionDeclaration()->get_name().getString();
    if(fn_name.compare("op_decl_const")==0) 
    {
      SgExprListExp* exprList = fn->get_args();
      SgExpressionPtrList &exprs = exprList->get_expressions();
      if( isSgStringVal(exprs.back()) == NULL )
      {
        SgVarRefExp* varExp = isSgVarRefExp(exprs[1]);
        if(!varExp)
        {
          varExp = isSgVarRefExp(isSgAddressOfOp(exprs[1])->get_operand_i());
        }

        if(varExp)
        {
          var_name = varExp->get_symbol()->get_name();
        }
        cout << "---Injecting Debug Name for const: " << var_name.getString() << "---" << endl;
        exprList->append_expression(buildStringVal(var_name));
      }
    }
  }
}
Example #6
0
/*
 * Check to see if a variable has its address taken in an I/O operation.
 */
bool RegisterPointers::isAddrTakenInIrrelevantFunc(SgVarRefExp* expr)
{
	//TODO get function call name
	/*SgExprStatement* stmt = isSgExprStatement(getEnclosingStatement(expr));
	if(!stmt)
		return false;
	SgFunctionCallExp* funcCall = isSgFunctionCallExp(stmt->get_expression());
	if(!funcCall)
		return false;
	string name = NAME(funcCall->getAssociatedFunctionSymbol());*/

	SgStatement* encStmt = getEnclosingStatement(expr);
	SgNode* parent = expr->get_parent();
	SgFunctionCallExp* funcCall = NULL;
	while(parent != encStmt)
	{
		funcCall = isSgFunctionCallExp(parent);
		if(funcCall &&
				(functions.find(NAME(funcCall->getAssociatedFunctionSymbol())) != functions.end()))
			return true;

		parent = parent->get_parent();
	}

	/*set<string>::const_iterator funcIt = functions.begin();
	for(funcIt = functions.begin(); funcIt != functions.end(); funcIt++)
	{
		if(name.find(*funcIt) != string::npos)
			return true;
	}*/
	return false;
}
Example #7
0
    bool findCallsWithFuncArgs2(SgNode *node, string &str) {		
	SgExprStatement *statement;
	if (statement = isSgExprStatement(node)) {
	    SgFunctionCallExp *call_exp;	
            if (call_exp = isSgFunctionCallExp(statement->get_the_expr())) {
                m_nodes.clear(); m_nodes.insert(call_exp);
                m_domain.expand(&m_nodes, QRQueryDomain::all_children);
                m_domain.getNodes()->erase(call_exp);
                NodeQuery::VariantVector vector (V_SgFunctionCallExp);
                QRQueryOpVariant op(vector);
                op.performQuery(&m_domain, &m_range);
                unsigned hits = m_range.countRange();
                if (hits) {
                    set<SgNode *> *rnodes = m_range.getNodes();
                    for (set<SgNode *>::iterator iter = rnodes->begin();
                         iter != rnodes->end(); )
                    {
                        SgFunctionCallExp *exp = (SgFunctionCallExp *) *iter; iter++;
                        SgExpression *funcexpr = exp->get_function();
                        str += funcexpr->unparseToString();
                        if (iter != rnodes->end()) {
                            str += ", ";
                        } 
                    }
                    return true;
                }
            }
	}
	
	return false;
    }
Example #8
0
void
CompassAnalyses::DiscardAssignment::Traversal::
visit(SgNode* node)
   { 
     if (isSgAssignOp(node))
     {
       // simple case: the parent of a "real" assignment op must be an
       // expression statement
       if (!isSgExprStatement(node->get_parent()))
       {
         output->addOutput(new CheckerOutput(node));
       }
       else
       {
         // not so simple case: the parent is an expression statement, but if
         // that statement is an if/loop condition, we still want to complain
         SgNode *assignment = node->get_parent();
         SgNode *p = assignment->get_parent();
         SgDoWhileStmt *dws;
         SgForStatement *fs;
         SgIfStmt *is;
         SgSwitchStatement *ss;
         SgWhileStmt *ws;

         if ((dws = isSgDoWhileStmt(p)) && dws->get_condition() == assignment)
         {
           output->addOutput(new CheckerOutput(node));
         }
         else if ((fs = isSgForStatement(p)) && fs->get_test() == assignment)
         {
           output->addOutput(new CheckerOutput(node));
         }
         else if ((is = isSgIfStmt(p)) && is->get_conditional() == assignment)
         {
           output->addOutput(new CheckerOutput(node));
         }
         else if ((ss = isSgSwitchStatement(p)) && ss->get_item_selector() == assignment)
         {
           output->addOutput(new CheckerOutput(node));
         }
         else if ((ws = isSgWhileStmt(p)) && ws->get_condition() == assignment)
         {
           output->addOutput(new CheckerOutput(node));
         }
       }
     }
     else if (SgMemberFunctionRefExp *mf = isSgMemberFunctionRefExp(node))
     {
       // not so simple case: call to operator= member function that is not an
       // expression statement by itself
       SgFunctionCallExp *call = isSgFunctionCallExp(mf->get_parent()->get_parent());
       if (call && !isSgExprStatement(call->get_parent())
        && mf->get_parent() == call->get_function()
        && std::strcmp(mf->get_symbol()->get_name().str(), "operator=") == 0)
       {
         output->addOutput(new CheckerOutput(call));
       }
     }
   } //End of the visit function.
Example #9
0
void SecureFunctionTypeTraversalTest::visit(SgNode* sgn)
{
    if(isSgFunctionCallExp(sgn)) {
        SecureFunctionType* attr = dynamic_cast<SecureFunctionType*> (sgn->getAttribute("SECURE_TYPE") );
        ROSE_ASSERT(attr != NULL);

        cout << sgn->unparseToString() << ": " ; (attr->isSecure()) ? cout << "trusted\n" : cout << "untrusted\n";
    }
}
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;
}
          virtual void visit(SgNode* n)
             {
#if 0
            // Debugging code
               if (!isSgInitializedName(n))
                    n->unparseToString();
#endif
               SgFunctionCallExp* n2 = isSgFunctionCallExp(n);
               if (n2)
                  {
                    calls_to_inline.push_back(n2);
                  }
             }
 virtual void visit(SgNode *node) { /*override*/
     SgFunctionCallExp *fcall = isSgFunctionCallExp(node);
     SgFunctionDeclaration *fdecl = fcall ? fcall->getAssociatedFunctionDeclaration() : NULL;
     std::string fname = fdecl ? fdecl->get_qualified_name().getString() : "";
     if (SageInterface::is_Java_language()) {
         if (0==fname.compare("System.getenv")) {
             found.push_back(fcall);
             CodeProperties::message(std::cout, fcall, "environment variable is read");
         }
     } else if (0==fname.compare("::getenv")) {
         found.push_back(fcall);
         CodeProperties::message(std::cout, fcall, "environment variable is read");
     }
 }
/*
 *  Replace the op_par_loop with respective kernel function
 */
void OPSource::fixParLoops(SgNode *n)
{
  SgName kernel_name;
  SgFunctionCallExp *fn = isSgFunctionCallExp(n);
  if(fn != NULL)
  {
    string fn_name = fn->getAssociatedFunctionDeclaration()->get_name().getString();
    if(fn_name.compare("op_par_loop_2")==0 
    || fn_name.compare("op_par_loop_3")==0 
    || fn_name.compare("op_par_loop_4")==0
    || fn_name.compare("op_par_loop_5")==0
    || fn_name.compare("op_par_loop_6")==0
    || fn_name.compare("op_par_loop_7")==0
    || fn_name.compare("op_par_loop_8")==0
    || fn_name.compare("op_par_loop_9")==0) 
    {
      SgExprListExp* exprList = fn->get_args();
      SgExpressionPtrList &exprs = exprList->get_expressions();
      SgFunctionRefExp* varExp =  isSgFunctionRefExp(exprs[0]);
      if(varExp != NULL)
      {
        kernel_name = varExp->get_symbol()->get_name();
      }
      exprs.erase(exprs.begin());

      SgExpressionPtrList::iterator it = exprs.begin() + op_par_loop_args::num_params - 1;
      for(; it != exprs.end(); it += op_argument::num_params)
      {
        *it = buildCastExp( *it, buildPointerType(SgClassType::createType( buildStructDeclaration("op_dat<void>"))) );
      }

      // Inject Name
      exprs.insert(exprs.begin(), buildStringVal(kernel_name));
      
      // Fetch the declaration
      SgName name = SgName("op_par_loop_") + kernel_name;
      SgFunctionDeclaration *funcDecl = cudaFunctionDeclarations[kernel_name];
      if(funcDecl)
      {
        SgFunctionRefExp* ref = isSgFunctionRefExp(fn->get_function());
        SgFunctionSymbol *symbol = ref->get_symbol();
        symbol->set_declaration(funcDecl);
        ref->set_symbol(symbol);
        fn->set_function(ref);
      }
    }
  }
}
Example #14
0
void pCFGIterator::filterSendRecv(const pCFGNode& pcfgn, set<unsigned int>& blockedPSets, 
                                  set<unsigned int>& sendPSets,
                                  set<unsigned int>& recvPSets)
{
    set<unsigned int>::iterator it;
    for(it = blockedPSets.begin(); it != blockedPSets.end(); it++) {
        const DataflowNode& dfnode = pcfgn.getCurNode(*it);
        SgNode* sgn = dfnode.getNode();
        Function callee(isSgFunctionCallExp(sgn));

        if(callee.get_name().getString() == "MPI_Send") {
            sendPSets.insert(*it);
        }
        else if(callee.get_name().getString() == "MPI_Recv") {
            recvPSets.insert(*it);
        }        
    }
}
Example #15
0
 void visit(SgNode *n) {
   switch (n->variantT()) {
   case V_SgStatementExpression: 
     reportError("GNU extension 'statement expression' is not allowed.", n);
     break;
   case V_SgFunctionCallExp: {
     SgFunctionCallExp *FCE = isSgFunctionCallExp(n);
     SgFunctionDeclaration *calleeFD = 
         FCE->getAssociatedFunctionDeclaration();
     if (!calleeFD) {
         reportError("calls through function pointers are not allowed.", n);
     }
     break;
     }
   default:
     break;
   }
 }
Example #16
0
ParseTree * ParseTree::extractParseTree(
  SgExpression * exp,
  const PolyhedricAnnotation::FunctionPolyhedralProgram & function_program,
  PolyGraph * polygraph,
  std::string isl_domain,
  unsigned stmt_id
) {
  SgBinaryOp * bin_op = isSgBinaryOp(exp);
  SgUnaryOp * una_op = isSgUnaryOp(exp);
  SgConditionalExp * cond_exp = isSgConditionalExp(exp);
  SgFunctionCallExp * func_call = isSgFunctionCallExp(exp);

  ParseTree * c1 = NULL;
  ParseTree * c2 = NULL;
  ParseTree * c3 = NULL;

  unsigned variant = exp->variantT();

  if (isSgPntrArrRefExp(exp)) bin_op = NULL;

  if (bin_op != NULL) {
    c1 = extractParseTree(bin_op->get_lhs_operand_i(), function_program, polygraph, isl_domain, stmt_id);
    c2 = extractParseTree(bin_op->get_rhs_operand_i(), function_program, polygraph, isl_domain, stmt_id);
  }
  else if (una_op != NULL) {
    c1 = extractParseTree(una_op->get_operand_i(), function_program, polygraph, isl_domain, stmt_id);
  }
  else if (cond_exp != NULL) {
    c1 = extractParseTree(cond_exp->get_conditional_exp(), function_program, polygraph, isl_domain, stmt_id);
    c2 = extractParseTree(cond_exp->get_true_exp(), function_program, polygraph, isl_domain, stmt_id);
    c3 = extractParseTree(cond_exp->get_false_exp(), function_program, polygraph, isl_domain, stmt_id);
  }
  else if (func_call != NULL) {
    std::vector<SgExpression *> args = func_call->get_args()->get_expressions();
    ROSE_ASSERT(args.size() == 1);
    c1 = extractParseTree(args[0], function_program, polygraph, isl_domain, stmt_id);
  }
  else {
    return new Data(polygraph, exp, function_program, isl_domain);
  }

  return new Operator(polygraph, variant, c1, c2, c3);
}
Example #17
0
		virtual void visit(SgNode * n) {
			switch (n->variantT()) {
				case V_SgFunctionDeclaration:
				{
					SgFunctionDeclaration * func_decl = isSgFunctionDeclaration(n);
					ROSE_ASSERT(func_decl != NULL);
					std::string func_name = func_decl->get_name().getString();
//					std::cout << "Found SgFunctionDeclaration: " << func_name << std::endl;
					if (func_name == "caller")
						p_caller = func_decl;
					if (func_name == "kernel")
						p_kernel = func_decl;
					break;
				}
				case V_SgForStatement:
				{
					SgForStatement * for_stmt = isSgForStatement(n);
					ROSE_ASSERT(for_stmt != NULL);
//					std::cout << "Found SgForStatement." << std::endl;
					p_for_stmts.push_back(for_stmt);
					break;
				}
				case V_SgFunctionCallExp:
				{
					SgFunctionCallExp * func_call = isSgFunctionCallExp(n);
					ROSE_ASSERT(func_call != NULL);
					SgFunctionRefExp * func_ref = isSgFunctionRefExp(func_call->get_function());
					ROSE_ASSERT(func_ref != NULL);
//					std::cout << "Found SgFunctionCallExp: " << func_ref->getAssociatedFunctionDeclaration ()->get_name().getString() << std::endl;
					if (func_ref->getAssociatedFunctionDeclaration()->get_name().getString() == "kernel")
						p_kernel_call_site = func_call;
					break;
				}
                                case V_SgSourceFile: // fix the file suffix, Liao 12/29/2010
                                {
                                     SgSourceFile * sfile = isSgSourceFile (n);
                                     ROSE_ASSERT (sfile != NULL);
                                     sfile->set_Cuda_only(true);
                                }
				default:{}
			}
		}
bool isHtThreadControlStmt(SgStatement *S)
{
  SgExprStatement *es = isSgExprStatement(S);
  SgFunctionCallExp *fce = 0;
  if (es && (fce = isSgFunctionCallExp(es->get_expression()))) {
    SgFunctionDeclaration *calleeFD = fce->getAssociatedFunctionDeclaration();
    std::string fname = calleeFD->get_name().getString();
    size_t pos = 0;
    if (fname == "WriteMemPause" ||
        fname == "ReadMemPause" ||
        fname == "HtBarrier" ||
        (((pos = fname.find("SendCall_")) != std::string::npos
         /*  || (pos = fname.find("SendCallFork_")) != std::string::npos */
           || (pos = fname.find("SendReturn_")) != std::string::npos
           || (pos = fname.find("RecvReturnJoin_")) != std::string::npos)
         && pos == 0)) {
      return true;
    }
  }
  return false;
}
Example #19
0
    bool findCallsWithFuncArgs(SgNode *node, string &str) {		
	SgExprStatement *statement;
	if (statement = isSgExprStatement(node)) {
	    SgFunctionCallExp *call_exp;	
            if (call_exp = isSgFunctionCallExp(statement->get_the_expr())) {
                m_nodes.clear(); m_nodes.insert(call_exp);
                m_domain.expand(&m_nodes, QRQueryDomain::all_children);
                m_domain.getNodes()->erase(call_exp);
                NodeQuery::VariantVector vector(V_SgFunctionCallExp);	       
                QRQueryOpVariant op(vector);
                op.performQuery(&m_domain, &m_range);
                unsigned hits = m_range.countRange();
                if (hits) {
                    sprintf(m_buffer, "%d", hits);
                    str = m_buffer;
                    return true;
                }
            }
	}
	
	return false;
    }
bool FortranAnalysis::matchRegionAssignment(SgExprStatement * expr_stmt)
{
   SgBinaryOp * bin_op = isSgBinaryOp(expr_stmt->get_expression());
   if (bin_op == NULL) return false;

   SgFunctionCallExp * fcall = isSgFunctionCallExp(bin_op->get_rhs_operand());
   if (fcall == NULL) return false;

   SgFunctionRefExp * fref = isSgFunctionRefExp(fcall->get_function());
   if (fref == NULL) return false;

   SgExpressionPtrList::iterator it = fcall->get_args()->get_expressions().begin();
   std::string name = fref->get_symbol()->get_name().getString();
   if (name == "interior" && it != fcall->get_args()->get_expressions().end()) {
      SgVarRefExp * var = isSgVarRefExp(*it);
      if (var == NULL) return false;
      AstTextAttribute * attr = (AstTextAttribute *) var->get_symbol()->getAttribute("dummy_attr");
      if (attr == NULL) return false;
      if (attr->toString() != "DUMMY_ARRAY_ARG") return false;
   }
   return true;
}
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);
   }
Example #22
0
void
CompassAnalyses::VariableNameEqualsDatabaseName::Traversal::
visit(SgNode* node)
   { 
     if( isSgAssignInitializer(node) != NULL )
          assignExp = node;
  
     if( isSgAssignOp(node) != NULL )
          assignExp = node; 

     SgFunctionCallExp* funcCall = isSgFunctionCallExp(node);

  // See if we have a dot expression or arrow expression which
  // accesses the desired member function in the class we are looking for.
     if ( funcCall != NULL  )
        {
          SgExpression* funcExp = funcCall->get_function();

          if ( ( isSgDotExp(funcExp) != NULL ) | ( isSgArrowExp(funcExp) != NULL ) )
             {
               SgBinaryOp*     binOp = isSgBinaryOp(funcExp);
               SgExpression*   rhsOp = binOp->get_rhs_operand();
            // SgExpression*   lhsOp = binOp->get_lhs_operand();
               if ( SgMemberFunctionRefExp* funcRef = isSgMemberFunctionRefExp(rhsOp)  )
                  {
                 // std::cout << "c1\n" ;

                    SgMemberFunctionSymbol*      funcSymbol = funcRef->get_symbol();
                    ROSE_ASSERT(funcSymbol->get_declaration() != NULL);

                 // DQ (1/16/2008): Note that the defining declaration need not exist (see test2001_11.C)
                 // ROSE_ASSERT(funcSymbol->get_declaration()->get_definingDeclaration() != NULL);
                    if (funcSymbol->get_declaration()->get_definingDeclaration() != NULL)
                       {
                         SgMemberFunctionDeclaration* funcDecl   = isSgMemberFunctionDeclaration(funcSymbol->get_declaration()->get_definingDeclaration());
                         ROSE_ASSERT( funcDecl != NULL );

                         SgClassDefinition* clDef = isSgClassDefinition(funcDecl->get_scope());
                         SgClassDeclaration*          clDecl     = isSgClassDeclaration(clDef->get_declaration());  

                      // SgClassDeclaration*          clDecl     = funcDecl->get_associatedClassDeclaration();

                         ROSE_ASSERT( clDecl != NULL );
                         std::string className    = clDecl->get_name().getString();

                         ROSE_ASSERT(funcDecl != NULL);
                         std::string functionName = funcDecl->get_name().getString();
 
                      // If the class is the class we are looking for see if the member function
                      // access is to the member function we are interested in.
                      // std::cout << "className = " << className << std::endl;
                      // std::cout << "functionName = " << functionName << std::endl;

                         if ( (className == classToLookFor) && ( functionName == memberFunctionToLookFor ) )
                            {
                              SgExprListExp*         actualArgs    = funcCall->get_args();
                              SgExpressionPtrList&   actualExpArgs = actualArgs->get_expressions ();

                              ROSE_ASSERT(actualExpArgs.size() == 1);
                              Rose_STL_Container<SgNode*> nodeLst = NodeQuery::querySubTree(*actualExpArgs.begin(), V_SgStringVal);

                              ROSE_ASSERT( nodeLst.size() > 0);
                              SgStringVal* actualArg = isSgStringVal(*nodeLst.begin());
                              ROSE_ASSERT(actualArg != NULL);

                              std::string  stringArg = actualArg->get_value();

                              std::cout << "arg:" << stringArg << std::endl;

                              std::string varName;

                           // SgInitializedName* initName = NULL; 
                              if ( SgAssignInitializer* assignInit =  isSgAssignInitializer(assignExp) )
                                 {
                                   SgInitializedName* initName = isSgInitializedName(assignInit->get_parent());
                                   ROSE_ASSERT(initName != NULL);
                                 
                                   varName = initName->get_name().getString();
                                 }
                                else
                                 {
                                   if ( SgAssignOp* assignOp = isSgAssignOp(assignExp) )
                                      {
                                        SgExpression*     lhsOp  = assignOp->get_lhs_operand();
                                        SgVarRefExp*      varRef = isSgVarRefExp(lhsOp);
                                        ROSE_ASSERT(varRef!=NULL);
                                        SgVariableSymbol* varSymbol = varRef->get_symbol();
                                        ROSE_ASSERT(varSymbol != NULL);
                                        SgInitializedName* initName = varSymbol->get_declaration();
                                        varName = initName->get_name().getString();
                                      }
                                 }
 
                              if (varName != "")
                                 {
                                // we are only interested in the part of the argument after the last ":"
                                // Database scopes in ALE3D are separated by ":"

                                   size_t posCol = stringArg.find_last_of(':');
                                 
                                   if (posCol != std::string::npos)
                                        stringArg = stringArg.substr(posCol+1);

                                 //Find violations to the rule
                                   if ( stringArg != varName)
                                      {
                                        output->addOutput(new CheckerOutput(assignExp));
                                        std::cout << "violation" << varName << std::endl;
                                      }
                                     else 
                                      {
                                        std::cout << "non=violation" << varName << std::endl;
                                      }
                                 }
                            }
                       }
                  }
             } 
        }
   } // End of the visit function.
Example #23
0
void
ProcTraversal::visit(SgNode *node) {
    if (isSgFunctionDeclaration(node)) {
        SgFunctionDeclaration *decl = isSgFunctionDeclaration(node);
        if (decl->get_definition() != NULL) {
            /* collect statistics */
            //AstNumberOfNodesStatistics anons;
            //anons.traverse(decl, postorder);
            //original_ast_nodes += anons.get_numberofnodes();
            //original_ast_statements += anons.get_numberofstatements();

            /* do the real work */
            Procedure *proc = new Procedure();
            proc->procnum = procnum++;
            proc->decl = decl;
            proc->funcsym
                = isSgFunctionSymbol(decl->get_symbol_from_symbol_table());
            if (proc->funcsym == NULL)
            {
#if 0
                std::cout
                        << std::endl
                        << "*** NULL function symbol for declaration "
                        << decl->unparseToString()
                        << std::endl
                        << "symbol: "
                        << (void *) decl->get_symbol_from_symbol_table()
                        << (decl->get_symbol_from_symbol_table() != NULL ?
                            decl->get_symbol_from_symbol_table()->class_name()
                            : "")
                        << std::endl
                        << "first nondef decl: "
                        << (void *) decl->get_firstNondefiningDeclaration()
                        << " sym: "
                        << (decl->get_firstNondefiningDeclaration() != NULL ?
                            (void *) decl->get_firstNondefiningDeclaration()
                            ->get_symbol_from_symbol_table()
                            : (void *) NULL)
                        << std::endl;
#endif
                if (decl->get_firstNondefiningDeclaration() != NULL)
                {
                    proc->funcsym = isSgFunctionSymbol(decl
                                                       ->get_firstNondefiningDeclaration()
                                                       ->get_symbol_from_symbol_table());
                }
            }
            assert(proc->funcsym != NULL);
            // GB (2008-05-14): We need two parameter lists: One for the names of the
            // variables inside the function definition, which is
            // decl->get_parameterList(), and one that contains any default arguments
            // the function might have. The default arguments are supposedly
            // associated with the first nondefining declaration.
            proc->params = decl->get_parameterList();
            SgDeclarationStatement *fndstmt = decl->get_firstNondefiningDeclaration();
            SgFunctionDeclaration *fnd = isSgFunctionDeclaration(fndstmt);
            if (fnd != NULL && fnd != decl)
                proc->default_params = fnd->get_parameterList();
            else
                proc->default_params = proc->params;

            SgMemberFunctionDeclaration *mdecl
                = isSgMemberFunctionDeclaration(decl);
            if (mdecl) {
                proc->class_type = isSgClassDefinition(mdecl->get_scope());
                std::string name = proc->class_type->get_mangled_name().str();
                name += "::";
                name += decl->get_name().str();
                std::string mname = proc->class_type->get_mangled_name().str();
                mname += "::";
                mname += decl->get_mangled_name().str();
                proc->memberf_name = name;
                proc->mangled_memberf_name = mname;
                proc->name = decl->get_name().str();
                proc->mangled_name = decl->get_mangled_name().str();
                // GB (2008-05-26): Computing a single this symbol for each
                // procedure. Thus, this symbol can also be compared by pointer
                // equality (as is the case for all other symbols). While we're at it,
                // we also build a VarRefExp for this which can be used everywhere the
                // this pointer occurs.
                proc->this_type = Ir::createPointerType(
                                      proc->class_type->get_declaration()->get_type());
                proc->this_sym = Ir::createVariableSymbol("this", proc->this_type);
                proc->this_exp = Ir::createVarRefExp(proc->this_sym);
            } else {
                proc->name = decl->get_name().str();
                proc->mangled_name = decl->get_mangled_name().str();
                proc->class_type = NULL;
                proc->memberf_name = proc->mangled_memberf_name = "";
                proc->this_type = NULL;
                proc->this_sym = NULL;
                proc->this_exp = NULL;
                // GB (2008-07-01): Better resolution of calls to static functions.
                // This only makes sense for non-member functions.
                SgStorageModifier &sm =
                    (fnd != NULL ? fnd : decl)->get_declarationModifier().get_storageModifier();
                proc->isStatic = sm.isStatic();
                // Note that we query the first nondefining declaration for the
                // static modifier, but we save the file of the *defining*
                // declaration. This is because the first declaration might be in
                // some header file, but for call resolution, the actual source
                // file with the definition is relevant.
                // Trace back to the enclosing file node. The definition might be
                // included in foo.c from bar.c, in which case the Sg_File_Info
                // would refer to bar.c; but for function call resolution, foo.c is
                // the relevant file.
                SgNode *p = decl->get_parent();
                while (p != NULL && !isSgFile(p))
                    p = p->get_parent();
                proc->containingFile = isSgFile(p);
            }
            proc_map.insert(std::make_pair(proc->name, proc));
            mangled_proc_map.insert(std::make_pair(proc->mangled_name, proc));
            std::vector<SgVariableSymbol* >* arglist
                = new std::vector<SgVariableSymbol* >();
            SgVariableSymbol *this_var = NULL, *this_temp_var = NULL;
            if (mdecl
                    || decl->get_parameterList() != NULL
                    && !decl->get_parameterList()->get_args().empty()) {
                proc->arg_block
                    = new BasicBlock(node_id, INNER, proc->procnum);
                if (mdecl) {
                    // GB (2008-05-26): We now compute the this pointer right at the
                    // beginning of building the procedure.
                    // this_var = Ir::createVariableSymbol("this", this_type);
                    this_var = proc->this_sym;
                    // std::string varname
                    //   = std::string("$") + proc->name + "$this";
                    // this_temp_var = Ir::createVariableSymbol(varname, proc->this_type);
                    this_temp_var = global_this_variable_symbol;
                    ParamAssignment* paramAssignment
                        = Ir::createParamAssignment(this_var, this_temp_var);
                    proc->arg_block->statements.push_back(paramAssignment);
                    arglist->push_back(this_var);
                    if (proc->name.find('~') != std::string::npos) {
                        arglist->push_back(this_temp_var);
                    }
                }
                SgInitializedNamePtrList params
                    = proc->params->get_args();
                SgInitializedNamePtrList::const_iterator i;
#if 0
                int parnum = 0;
                for (i = params.begin(); i != params.end(); ++i) {
                    SgVariableSymbol *i_var = Ir::createVariableSymbol(*i);
                    std::stringstream varname;
                    // varname << "$" << proc->name << "$arg_" << parnum++;
                    SgVariableSymbol* var =
                        Ir::createVariableSymbol(varname.str(),(*i)->get_type());
                    proc->arg_block->statements.push_back(Ir::createParamAssignment(i_var, var));
                    arglist->push_back(i_var);
                }
#else
                // GB (2008-06-23): Trying to replace all procedure-specific argument
                // variables by a global list of argument variables. This means that at
                // this point, we do not necessarily need to build a complete list but
                // only add to the CFG's argument list if it is not long enough.
                size_t func_params = params.size();
                size_t global_args = global_argument_variable_symbols.size();
                std::stringstream varname;
                while (global_args < func_params)
                {
                    varname.str("");
                    varname << "$tmpvar$arg_" << global_args++;
                    SgVariableSymbol *var
                        = Ir::createVariableSymbol(varname.str(),
                                                   global_unknown_type);
                    program->global_map[varname.str()]
                        = std::make_pair(var, var->get_declaration());
                    global_argument_variable_symbols.push_back(var);
                }
                // now create the param assignments
                size_t j = 0;
                for (i = params.begin(); i != params.end(); ++i)
                {
                    SgVariableSymbol *i_var = Ir::createVariableSymbol(params[j]);
                    SgVariableSymbol *var = global_argument_variable_symbols[j];
                    j++;
                    proc->arg_block->statements.push_back(
                        Ir::createParamAssignment(i_var, var));
                    arglist->push_back(i_var);
                }
#if 0
                // replace the arglist allocated above by the new one; this must be
                // fixed for this pointers!
                delete arglist;
                arglist = &global_argument_variable_symbols;
#endif
#endif
            } else {
                proc->arg_block = NULL;
            }
            /* If this is a constructor, call default constructors
             * of all base classes. If base class constructors are
             * called manually, these calls will be removed later. */
            if (mdecl
                    && strcmp(mdecl->get_name().str(),
                              proc->class_type->get_declaration()->get_name().str()) == 0
                    && proc->class_type != NULL) {
                SgBaseClassPtrList::iterator base;
                for (base = proc->class_type->get_inheritances().begin();
                        base != proc->class_type->get_inheritances().end();
                        ++base) {
                    SgClassDeclaration* baseclass = (*base)->get_base_class();
                    SgVariableSymbol *lhs
                        = Ir::createVariableSymbol("$tmpvar$" + baseclass->get_name(),
                                                   baseclass->get_type());
                    program->global_map["$tmpvar$" + baseclass->get_name()]
                        = std::make_pair(lhs, lhs->get_declaration());
                    SgMemberFunctionDeclaration* fd=get_default_constructor(baseclass);
                    assert(fd);
                    SgType* basetype=baseclass->get_type();
                    assert(basetype);
                    SgConstructorInitializer *sci
                        = Ir::createConstructorInitializer(fd,basetype);
                    ArgumentAssignment* a
                        = Ir::createArgumentAssignment(lhs, sci);
                    proc->arg_block->statements.push_back(a);

                    // std::string this_called_varname
                    //   = std::string("$") + baseclass->get_name() + "$this";
                    SgVariableSymbol *this_called_var
                    // = Ir::createVariableSymbol(this_called_varname,
                    //                            baseclass->get_type());
                        = global_this_variable_symbol;
                    ReturnAssignment* this_ass
                        = Ir::createReturnAssignment(this_var, this_called_var);
                    proc->arg_block->statements.push_back(this_ass);
                }
            }
            if (mdecl && mdecl->get_CtorInitializerList() != NULL
                    && !mdecl->get_CtorInitializerList()->get_ctors().empty()) {
                SgInitializedNamePtrList cis
                    = mdecl->get_CtorInitializerList()->get_ctors();
                SgInitializedNamePtrList::const_iterator i;
                if (proc->arg_block == NULL) {
                    proc->arg_block = new BasicBlock(node_id, INNER, proc->procnum);
                }
                for (i = cis.begin(); i != cis.end(); ++i) {
                    SgVariableSymbol* lhs = Ir::createVariableSymbol(*i);
                    SgAssignInitializer *ai
                        = isSgAssignInitializer((*i)->get_initializer());
                    SgConstructorInitializer *ci
                        = isSgConstructorInitializer((*i)->get_initializer());
                    /* TODO: other types of initializers */
                    if (ai) {
                        SgClassDeclaration *class_decl
                            = proc->class_type->get_declaration();
                        // GB (2008-05-26): We now compute the this pointer right at the
                        // beginning of building the procedure.
                        // SgVarRefExp* this_ref
                        //   = Ir::createVarRefExp("this",
                        //                         Ir::createPointerType(class_decl->get_type()));
                        SgVarRefExp* this_ref = proc->this_exp;
                        SgArrowExp* arrowExp
                            = Ir::createArrowExp(this_ref,Ir::createVarRefExp(lhs));
                        // GB (2008-03-17): We need to handle function calls in
                        // initializers. In order to be able to build an argument
                        // assignment, we need to know the function's return variable, so
                        // the expression labeler must be called on it. The expression
                        // number is irrelevant, however, as it does not appear in the
                        // return variable.
                        if (isSgFunctionCallExp(ai->get_operand_i())) {
#if 0
                            ExprLabeler el(0 /*expnum*/);
                            el.traverse(ai->get_operand_i(), preorder);
                            // expnum = el.get_expnum();
#endif
                            // GB (2008-06-25): There is now a single global return
                            // variable. This may or may not mean that we can simply ignore
                            // the code above. I don't quite understand why this labeling
                            // couldn't be done later on, and where its result was used.
                        }
                        ArgumentAssignment* argumentAssignment
                            = Ir::createArgumentAssignment(arrowExp,ai->get_operand_i());
                        proc->arg_block->statements.push_back(argumentAssignment);
                    } else if (ci) {
                        /* if this is a call to a base class's
                         * constructor, remove the call we generated
                         * before */
                        SgStatement* this_a = NULL;
                        SgClassDeclaration* cd = ci->get_class_decl();
                        std::deque<SgStatement *>::iterator i;
                        for (i = proc->arg_block->statements.begin();
                                i != proc->arg_block->statements.end();
                                ++i) {
                            ArgumentAssignment* a
                                = dynamic_cast<ArgumentAssignment *>(*i);
                            if (a && isSgConstructorInitializer(a->get_rhs())) {
                                SgConstructorInitializer* c
                                    = isSgConstructorInitializer(a->get_rhs());
                                std::string c_decl_name = c->get_class_decl()->get_name().str();
                                std::string cd_name = cd->get_name().str();
                                // if (c->get_class_decl()->get_name() == cd->get_name()) {
                                if (c_decl_name == cd_name) {
#if 0
                                    // erase the following assignment
                                    // of the this pointer as well
                                    this_a = *proc->arg_block->statements.erase(i+1);
                                    proc->arg_block->statements.erase(i);
#endif
                                    // GB (2008-03-28): That's an interesting piece of code, but
                                    // it might be very mean to iterators. At least it is hard to
                                    // see whether it is correct. So let's try it like this:
                                    // erase i; we get an iterator back, which refers to the next
                                    // element. Save that element as this_a, and then erase.
                                    std::deque<SgStatement *>::iterator this_pos;
                                    this_pos = proc->arg_block->statements.erase(i);
                                    this_a = *this_pos;
                                    proc->arg_block->statements.erase(this_pos);
                                    // Good. Looks like this fixed a very obscure bug.
                                    break;
                                }
                            }
                        }
                        /* now add the initialization */
                        proc->arg_block->statements.push_back(Ir::createArgumentAssignment(lhs, ci));
                        if (this_a != NULL)
                            proc->arg_block->statements.push_back(this_a);
                    }
                }
            }
            proc->entry = new CallBlock(node_id++, START, proc->procnum,
                                        new std::vector<SgVariableSymbol *>(*arglist),
                                        (proc->memberf_name != ""
                                         ? proc->memberf_name
                                         : proc->name));
            proc->exit = new CallBlock(node_id++, END, proc->procnum,
                                       new std::vector<SgVariableSymbol *>(*arglist),
                                       (proc->memberf_name != ""
                                        ? proc->memberf_name
                                        : proc->name));
            proc->entry->partner = proc->exit;
            proc->exit->partner = proc->entry;
            proc->entry->call_target = Ir::createFunctionRefExp(proc->funcsym);
            proc->exit->call_target = Ir::createFunctionRefExp(proc->funcsym);
            /* In constructors, insert an assignment $A$this = this
             * at the end to make sure that the 'this' pointer can be
             * passed back to the calling function uncobbled. */
            proc->this_assignment = NULL;
            if (mdecl) {
                SgMemberFunctionDeclaration* cmdecl
                    = isSgMemberFunctionDeclaration(mdecl->get_firstNondefiningDeclaration());
                // if (cmdecl && cmdecl->get_specialFunctionModifier().isConstructor()) {
                proc->this_assignment
                    = new BasicBlock(node_id++, INNER, proc->procnum);
                ReturnAssignment* returnAssignment
                    = Ir::createReturnAssignment(this_temp_var, this_var);
                proc->this_assignment->statements.push_back(returnAssignment);
                add_link(proc->this_assignment, proc->exit, NORMAL_EDGE);
                // }
            }
            std::stringstream varname;
            // varname << "$" << proc->name << "$return";
            // proc->returnvar = Ir::createVariableSymbol(varname.str(),
            //                                            decl->get_type()->get_return_type());
            proc->returnvar = global_return_variable_symbol;
            procedures->push_back(proc);
            if(getPrintCollectedFunctionNames()) {
                std::cout << (proc->memberf_name != ""
                              ? proc->memberf_name
                              : proc->name)
                          << " " /*<< proc->decl << std::endl*/;
            }
            if (proc->arg_block != NULL)
            {
                proc->arg_block->call_target
                    = Ir::createFunctionRefExp(proc->funcsym);
            }
            // delete arglist;
        }
    }
}
Example #24
0
InheritedAttribute
visitorTraversal::evaluateInheritedAttribute(SgNode* n, InheritedAttribute inheritedAttribute)
   {
    Sg_File_Info* s = n->get_startOfConstruct();
    Sg_File_Info* e = n->get_endOfConstruct();
    Sg_File_Info* f = n->get_file_info();
    for(int x=0; x < inheritedAttribute.depth; ++x) {
        printf(" ");
    }
    if(s != NULL && e != NULL && !isSgLabelStatement(n)) { 
        printf ("%s (%d, %d, %d)->(%d, %d): %s",n->sage_class_name(),s->get_file_id()+1,s->get_raw_line(),s->get_raw_col(),e->get_raw_line(),e->get_raw_col(),  verbose ? n->unparseToString().c_str() : "" );
        if(isSgAsmDwarfConstruct(n)) {
            printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str());
        }
        SgExprStatement * exprStmt = isSgExprStatement(n);
        if(exprStmt != NULL) {
            printf(" [expr type: %s]", exprStmt->get_expression()->sage_class_name());           
            SgFunctionCallExp * fcall = isSgFunctionCallExp(exprStmt->get_expression());
            if(fcall != NULL) {
               SgExpression * funcExpr = fcall->get_function();
               if(funcExpr != NULL) {
                    printf(" [function expr: %s]", funcExpr->class_name().c_str());
               }
               SgFunctionDeclaration * fdecl = fcall->getAssociatedFunctionDeclaration();
               if(fdecl != NULL) {
                    printf(" [called function: %s]", fdecl->get_name().str());
               }
            }
        }
        if(isSgFunctionDeclaration(n)) {
            printf(" [declares function: %s]", isSgFunctionDeclaration(n)->get_name().str());
        }
        SgStatement * sgStmt = isSgStatement(n);
        if(sgStmt != NULL) {
            printf(" [scope: %s, %p]", sgStmt->get_scope()->sage_class_name(), sgStmt->get_scope());
        }
        //SgLabelStatement * lblStmt = isSgLabelStatement(n);
        //if(lblStmt != NULL) {
        //    SgStatement * lblStmt2 = lblStmt->get_statement();
        //}
    } else if (f != NULL) {
		SgInitializedName * iname = isSgInitializedName(n);
		if(iname != NULL) {
            SgType* inameType = iname->get_type();
			printf("%s (%d, %d, %d): %s [type: %s", n->sage_class_name(),f->get_file_id()+1,f->get_raw_line(),f->get_raw_col(),n->unparseToString().c_str(),inameType->class_name().c_str());
			SgDeclarationStatement * ds = isSgDeclarationStatement(iname->get_parent());
			if(ds != NULL) {
				if(ds->get_declarationModifier().get_storageModifier().isStatic()) {
					printf(" static");
				}
			}
			
			SgArrayType * art = isSgArrayType(iname->get_type());
			if(art != NULL) {
				printf(" %d", art->get_rank());
			}
			
			printf("]");
            if(isSgAsmDwarfConstruct(n)) {
                printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str());
            }
            } else {
        	printf("%s (%d, %d, %d): %s", n->sage_class_name(),f->get_file_id()+1,f->get_raw_line(),f->get_raw_col(), verbose ? n->unparseToString().c_str() : "");
		}
    } else {
        printf("%s : %s", n->sage_class_name(), verbose ? n->unparseToString().c_str() : "");
        if(isSgAsmDwarfConstruct(n)) {
            printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str());
        }
    }
    printf(" succ# %lu", n->get_numberOfTraversalSuccessors());
	printf("\n");
     return InheritedAttribute(inheritedAttribute.depth+1);
   }
int main(int argc, char **argv)
{
  SgProject *project = frontend(argc, argv);
  
  // Instantiate a class hierarchy wrapper.
  ClassHierarchyWrapper classHierarchy( project );

  std::list<SgNode *> nodes2 = NodeQuery::querySubTree(project,
						      V_SgVariableDefinition);

  for (std::list<SgNode *>::iterator it = nodes2.begin();
       it != nodes2.end(); ++it ) {

    SgNode *n = *it;
    ROSE_ASSERT(n != NULL);

    SgVariableDefinition *varDefn =
      isSgVariableDefinition(n);
    ROSE_ASSERT(varDefn != NULL);

    std::cout << "Var defn: " << varDefn->unparseToCompleteString() << std::endl;

  }

  std::list<SgNode *> nodes1 = NodeQuery::querySubTree(project,
						      V_SgVariableDeclaration);

  for (std::list<SgNode *>::iterator it = nodes1.begin();
       it != nodes1.end(); ++it ) {

    SgNode *n = *it;
    ROSE_ASSERT(n != NULL);

    SgVariableDeclaration *varDecl =
      isSgVariableDeclaration(n);
    ROSE_ASSERT(varDecl != NULL);

    SgInitializedNamePtrList &variables =
      varDecl->get_variables();
    SgInitializedNamePtrList::iterator varIter;
    for (varIter = variables.begin(); 
	 varIter != variables.end(); ++varIter) {
      
      SgNode *var = *varIter;
      ROSE_ASSERT(var != NULL);
      
      SgInitializedName *initName =
	isSgInitializedName(var);
      ROSE_ASSERT(initName != NULL);
      
      if ( isSgClassType(initName->get_type()) ) {

	SgClassType *classType = isSgClassType(initName->get_type());
	ROSE_ASSERT(classType != NULL);

	SgDeclarationStatement *declStmt = classType->get_declaration();
	ROSE_ASSERT(declStmt != NULL);
	
	SgClassDeclaration *classDeclaration = isSgClassDeclaration(declStmt);
	ROSE_ASSERT(classDeclaration != NULL);
      
	//	std::cout << "From var decl got: " << classDeclaration->unparseToCompleteString() << std::endl;

	SgClassDefinition *classDefinition =
	  classDeclaration->get_definition();
	if ( classDefinition != NULL ) {
	  std::cout << "From var decl got: " << classDefinition->unparseToCompleteString() << std::endl;
	}

      }

    }
    

  }

  std::list<SgNode *> nodes = NodeQuery::querySubTree(project,
						      V_SgClassDeclaration);

  for (std::list<SgNode *>::iterator it = nodes.begin();
       it != nodes.end(); ++it ) {

    SgNode *n = *it;
    ROSE_ASSERT(n != NULL);

    SgClassDeclaration *classDeclaration1 =
      isSgClassDeclaration(n);
    ROSE_ASSERT(classDeclaration1 != NULL);

    SgDeclarationStatement *definingDecl =
      classDeclaration1->get_definingDeclaration();
    if ( definingDecl == NULL )
      continue;
    
    SgClassDeclaration *classDeclaration =
      isSgClassDeclaration(definingDecl);
    ROSE_ASSERT(classDeclaration != NULL);


    SgClassDefinition *classDefinition =
      classDeclaration->get_definition();
    ROSE_ASSERT(classDefinition != NULL);

    std::cout << "Calling getSubclasses on " << classDefinition->unparseToCompleteString() << std::endl;

    SgClassDefinitionPtrList subclasses = 
      classHierarchy.getSubclasses(classDefinition);

    // Iterate over all subclasses.
    for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin();
	 subclassIt != subclasses.end(); ++subclassIt) {
      
      SgClassDefinition *subclass = *subclassIt;
      ROSE_ASSERT(subclass != NULL);
      
      std::cout << "subclass" << std::endl;

    }

  }
#if 0
#if 0
  std::list<SgNode *> nodes = NodeQuery::querySubTree(project,
						      V_SgClassDefinition);

  for (std::list<SgNode *>::iterator it = nodes.begin();
       it != nodes.end(); ++it ) {

    SgNode *n = *it;
    ROSE_ASSERT(n != NULL);

    SgClassDefinition *classDefinition =
      isSgClassDefinition(n);
    ROSE_ASSERT(classDefinition != NULL);

    std::cout << "Calling getSubclasses on " << classDefinition->unparseToCompleteString() << std::endl;

    SgClassDefinitionPtrList subclasses = 
      classHierarchy.getSubclasses(classDefinition);

    // Iterate over all subclasses.
    for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin();
	 subclassIt != subclasses.end(); ++subclassIt) {
      
      SgClassDefinition *subclass = *subclassIt;
      ROSE_ASSERT(subclass != NULL);
      
      std::cout << "subclass" << std::endl;

    }

  }
#else
  // Collect all function/method invocations.
  std::list<SgNode *> nodes = NodeQuery::querySubTree(project,
						      V_SgFunctionCallExp);

  unsigned int numCallSites = 0;
  unsigned int numMonomorphicCallSites = 0;
  unsigned int numPossibleResolutions = 0;

  // Visit each call site.
  for (std::list<SgNode *>::iterator it = nodes.begin();
       it != nodes.end(); ++it ) {

    SgNode *n = *it;
    ROSE_ASSERT(n != NULL);

    SgFunctionCallExp *functionCallExp =
      isSgFunctionCallExp(n);
    ROSE_ASSERT(functionCallExp != NULL);

    // We are only interested in examining method invocations.
    bool isDotExp = false;
    if ( !isMethodCall(functionCallExp, isDotExp) )
      continue;
    
    numCallSites++;
    // Certainly can be resolved to the static method.
    numPossibleResolutions++;

    if ( isDotExp ) {
      // If this is a dot expression (i.e., a.foo()), we can
      // statically determine its type.
      numMonomorphicCallSites++;
      continue;
    }

    // Retrieve the static function declaration.
    SgFunctionDeclaration *functionDeclaration = 
      getFunctionDeclaration(functionCallExp);

    // Ensure it is actually a method declaration.
    SgMemberFunctionDeclaration *memberFunctionDeclaration =
      isSgMemberFunctionDeclaration(functionDeclaration);
    ROSE_ASSERT(memberFunctionDeclaration != NULL);

    unsigned int numOverridesForMethod = 0;

    if ( ( isVirtual(functionDeclaration) ) ||
	 ( isDeclaredVirtualWithinAncestor(functionDeclaration) ) ) {
      
      SgClassDefinition *classDefinition = 
	isSgClassDefinition(memberFunctionDeclaration->get_scope());
      ROSE_ASSERT(classDefinition != NULL);
      
      SgClassDefinitionPtrList subclasses = 
	classHierarchy.getSubclasses(classDefinition);

      // Iterate over all subclasses.
      for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin();
	   subclassIt != subclasses.end(); ++subclassIt) {

	SgClassDefinition *subclass = *subclassIt;
	ROSE_ASSERT(subclass != NULL);

	std::cout << "subclass" << std::endl;

	// Iterate over all of the methods defined in this subclass.
	SgDeclarationStatementPtrList &decls =
	  subclass->get_members();
	for (SgDeclarationStatementPtrList::iterator declIter = decls.begin();
	     declIter != decls.end(); ++declIter) {

	  SgDeclarationStatement *declStmt = *declIter;
	  ROSE_ASSERT(declStmt != NULL);

	  SgMemberFunctionDeclaration *method =
	    isSgMemberFunctionDeclaration(declStmt);
	  if ( method == NULL ) {
	    continue;
	  }

	  // Determine whether subclass of the class defining this
	  // method overrides the method.
	  if ( methodOverridesVirtualMethod(method, 
					    memberFunctionDeclaration) ) {
	    numOverridesForMethod++;
	  }

	}

      }

      if ( numOverridesForMethod == 0 )
	numMonomorphicCallSites++;
      numPossibleResolutions += numOverridesForMethod;

      std::cout << "Method invocation has " << numOverridesForMethod + 1 << " possible resolutions " << std::endl;
      std::cout << functionCallExp->unparseToCompleteString() << std::endl;

    }

  }
#endif
#endif
  return 0;
}
void VirtualFunctionAnalysis::run()
   {

     printf ("In VirtualFunctionAnalysis::run() \n");

        vector<SgExpression*> callSites = SageInterface::querySubTree<SgExpression> (project, V_SgFunctionCallExp);

     printf ("In VirtualFunctionAnalysis::run(): after querySubTree on V_SgFunctionCallExp \n");

        vector<SgExpression*> constrs = SageInterface::querySubTree<SgExpression> (project, V_SgConstructorInitializer);

     printf ("In VirtualFunctionAnalysis::run(): callSites.insert() \n");

        callSites.insert(callSites.end(), constrs.begin(), constrs.end());

     printf ("DONE: VirtualFunctionAnalysis::run(): callSites.insert() \n");

        // Not all SgFunctionCallExp or SgConstructorInitialize nodes appear in functions--some are also in templates (for
        // classes or functions) and we don't want to process those. Templates are not really part of a control flow graph or
        // call graph until after they're instantiated.
        for (vector<SgExpression*>::iterator csi=callSites.begin(); csi!=callSites.end(); ++csi) {
            if (SgFunctionDeclaration *fdecl = SageInterface::getEnclosingNode<SgFunctionDeclaration>(*csi)) {
                if (isSgTemplateMemberFunctionDeclaration(fdecl) || isSgTemplateFunctionDeclaration(fdecl))
                    *csi = NULL;
            }

          printf ("In VirtualFunctionAnalysis::run(): loop 1 \n");

        }

          printf ("In VirtualFunctionAnalysis::run(): erase \n");

        callSites.erase(std::remove(callSites.begin(), callSites.end(), (SgExpression*)NULL), callSites.end());
        
          printf ("DONE: VirtualFunctionAnalysis::run(): erase \n");

        unsigned int index;
        resolver.clear();

          printf ("DONE: VirtualFunctionAnalysis::run(): clear \n");

        for(index = 0; index < callSites.size(); index++) {
            std::vector<SgFunctionDeclaration *> funcs;
            
          printf ("In VirtualFunctionAnalysis::run(): getPropertiesForExpression() \n");

            CallTargetSet::getPropertiesForExpression(callSites[index], classHierarchy, funcs);
            
            //Virtual Function
            if(isSgFunctionCallExp(callSites[index]) && funcs.size() > 1 )
                funcs.clear();
            resolver[callSites[index]] = funcs;

          printf ("In VirtualFunctionAnalysis::run(): loop 2 \n");
        }
        
          printf ("In VirtualFunctionAnalysis::run(): PtrAliasAnalysis::run() \n");

        PtrAliasAnalysis::run();
        
          printf ("DONE: VirtualFunctionAnalysis::run(): PtrAliasAnalysis::run() \n");

        for(index = 0; index < callSites.size(); index++) {
            if(resolver.at(callSites[index]).size() == 0  ) {
                std::vector<SgFunctionDeclaration *> funcs;
                CallTargetSet::getPropertiesForExpression(callSites[index], classHierarchy, funcs);
                resolver[callSites[index]] = funcs;
            }

          printf ("In VirtualFunctionAnalysis::run(): loop 3 \n");
        }
        isExecuted = true;

     printf ("Leaving VirtualFunctionAnalysis::run() \n");
   }
Example #27
0
 // on other nodes
 lrRecord (lrRecord &parent, SgNode* n)
 {
         SgBinaryOp* binOp;
         SgUnaryOp* unOp;
         SgFunctionCallExp* funcCall;
         //SgPntrArrRefExp* arrRef;
         char typeStr[100];
         
         // if this node is on the read, write or read-write side of an assignment operation, set its access appropriately
         if(parent.readSubtree == n)
                 access = readAccess;
         else if(n == parent.writeSubtree)
                 access = writeAccess;
         else if(n == parent.rwSubtree)
                 access = rwAccess;
         else
                 access = parent.access;
         
         if((binOp = isSgBinaryOp(n)))
         {                       
                 // writeSubtree = readSubtree
                 if(isSgAssignOp(binOp))
                 {
                         writeSubtree = binOp->get_lhs_operand();
                         readSubtree = binOp->get_rhs_operand();
                         rwSubtree = (void*)NULL;
                         strcpy(typeStr, "SgAssignOp");
                 }
                 // rwSubtree op= readSubtree
                 else if(isSgCompoundAssignOp(binOp))
                 {
                         rwSubtree = binOp->get_lhs_operand();
                         readSubtree = binOp->get_rhs_operand();
                         writeSubtree = (void*)NULL;
                         strcpy(typeStr, "Sg*AssignOp");
                 }
                 else if(isSgPntrArrRefExp(binOp))
                 {
                         // all the references involved in an array reference, whether they are used to compute the array name
                         // or used in the argument, are read-only
                         writeSubtree = (void*)NULL;
                         readSubtree = (void*)NULL;
                         readSubtree.wildMatch();
                         rwSubtree = (void*)NULL;
                         strcpy(typeStr, "SgPntrArrRefExp");
                 }
                 else 
                 {
                         readSubtree = (void*)NULL;
                         writeSubtree = (void*)NULL;
                         rwSubtree = (void*)NULL;
                         strcpy(typeStr, "???");
                 }
                 
                 //printf("SgBinaryNode 0x%x type %s access=%d: %s\n", binOp, typeStr, access, binOp->unparseToString().c_str());        
         }
         else if((unOp = isSgUnaryOp(n)))
         {
                 // unary update operations have only one operand, which is read-write
                 // writeSubtree
                 if(isSgMinusMinusOp(unOp) ||
                         isSgPlusPlusOp(unOp))
                 {
                         writeSubtree = (void*)NULL;
                         readSubtree = (void*)NULL;
                         rwSubtree = unOp->get_operand();
                         strcpy(typeStr, "Sg**Op");
                 }
                 // dereference operations have a read-only operand
                 else if(isSgPointerDerefExp(unOp))
                 {
                         writeSubtree = (void*)NULL;
                         readSubtree = unOp->get_operand();
                         rwSubtree = (void*)NULL;
                         strcpy(typeStr, "isSgPointerDerefExp");
                 }
                 else 
                 {
                         readSubtree = (void*)NULL;
                         writeSubtree = (void*)NULL;
                         rwSubtree = (void*)NULL;
                         strcpy(typeStr, "???");
                 }
                 //printf("SgUnaryNode 0x%x %s access=%d: %s\n", unOp, typeStr, access, unOp->unparseToString().c_str());
         }
         else if((funcCall = isSgFunctionCallExp(n)))
         {
                 // all the references involved in a function call, whether they are used to compute the function pointer
                 // or used in the argument, are read-only
                 writeSubtree = (void*)NULL;
                 readSubtree = (void*)NULL;
                 readSubtree.wildMatch();
                 rwSubtree = (void*)NULL;
                 //printf("SgFunctionCall 0x%x access=%d: %s\n", funcCall, access, funcCall->unparseToString().c_str());
         }
         // else, if this is neither a binary, nor unary operation node
         else
         {
                 // leave subtree fields of this record as NULL
                 readSubtree = (void*)NULL;
                 writeSubtree = (void*)NULL;
                 rwSubtree = (void*)NULL;
                 
                 //printf("SgNode 0x%x access=%d: %s\n", n, access, n->unparseToString().c_str());
         }
 }
/** Visits AST nodes in post-order. This is function-evaluation order. */
bool FunctionEvaluationOrderTraversal::evaluateSynthesizedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute, SynthesizedAttributesList)
{
    SgFunctionCallExp* functionCall = isSgFunctionCallExp(astNode);
    if (functionCall == NULL)
        return false; //dummy return value
    
    FunctionCallInfo functionCallInfo(functionCall);

    // Can't lift function call arguments from the following:
    // 1. For loop test and increment
    // 2. While loop test
    // 3. Do-While loop test
    // 4. Either arms of ternary op
    // 5. RHS of any short circuit expression
    // An alternative is to use comma operators and use assignemnt op as done by the original author. 
    // for(;foo(bar());) ==> T i; for(;i=bar();foo(i);)
    // But using assignement op is not always safe and it requires us to always have a default constructor
    // There is also an issue when the return type is a reference and we'll have to use & op to get a pointer
    // but if & op is overloaded we may not get the pointer.
    // Taking all these in view, I am simpling not lifting such expressions.
    
    if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_TEST ||
        parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_INCREMENT ||
        parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_WHILE_CONDITION ||
        parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_DO_WHILE_CONDITION) {

        // ***** FOR UNSAFE TRANSFORMATION *******
        //Temporary variables should be declared before the stmt
        ROSE_ASSERT(isSgStatement(parentAttribute.currentScope));
        functionCallInfo.tempVarDeclarationLocation = isSgStatement(parentAttribute.currentScope);
        functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE;

        nonNormalizableFunctionCalls.push_back(functionCallInfo);
        return false;
    }

    // In future, if the function call is assured to be side effect free, then we can lift it from short circuit and conditional expressions
    if(parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_TRUE_ARM ||
       parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_FALSE_ARM ||
       parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS){
        
        if(!IsFunctionCallSideEffectFree(functionCall)) {
            
            // ***** FOR UNSAFE TRANSFORMATION *******
            //Temporary variables should be declared before the stmt
            ROSE_ASSERT(parentAttribute.lastStatement);
            functionCallInfo.tempVarDeclarationLocation = parentAttribute.lastStatement;
            functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE;

            nonNormalizableFunctionCalls.push_back(functionCallInfo);
            return false;
        }
    }
    
    //Handle for loops (being inside the body of a for loop doesn't need special handling)
    if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_INIT)
    {
        SgForStatement* forLoop = isSgForStatement(parentAttribute.currentScope);
        ROSE_ASSERT(forLoop != NULL);
        //Temporary variables should be declared before the loop
        functionCallInfo.tempVarDeclarationLocation = forLoop;
        functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE;
    }
    else if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE)
    {
        //Assume we're in a basic block. Then just insert right before the current statement
        ROSE_ASSERT(parentAttribute.scopeStatus = FunctionCallInheritedAttribute::IN_SAFE_PLACE);
        functionCallInfo.tempVarDeclarationLocation = parentAttribute.lastStatement;
        functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE;
    }
    else
    {
        //Unhandled condition?!
        ROSE_ASSERT(false);
    }

    normalizableFunctionCalls.push_back(functionCallInfo);
    return false; //dummy return value
}