예제 #1
0
파일: ENV.C 프로젝트: 8l/rose
/**
 * No atexit handler should terminate in any way other than by returning
 * \note This catches calls to exit, _exit, _abort, _Exit, longjmp and
 * siglongjmp
 */
bool ENV32_C( const SgNode *node ) {
	const SgFunctionRefExp *fnRef = isSgFunctionRefExp(node);
	if (!(fnRef && isCallOfFunctionNamed(fnRef, "atexit")))
		return false;

	const SgFunctionRefExp* ref = isSgFunctionRefExp(getFnArg(fnRef, 0));
	assert(ref);

	const SgFunctionDeclaration *fnDecl = ref->get_symbol()->get_declaration();
	assert(fnDecl);

	bool violation = false;

	FOREACH_SUBNODE(fnDecl,nodes,i,V_SgFunctionRefExp) {
		const SgFunctionRefExp *iFn = isSgFunctionRefExp(*i);
		assert(iFn);
		if(isCallOfFunctionNamed( iFn, "exit")
		|| isCallOfFunctionNamed( iFn, "_exit")
		|| isCallOfFunctionNamed( iFn, "abort")
		|| isCallOfFunctionNamed( iFn, "_Exit")
		|| isCallOfFunctionNamed( iFn, "longjmp")
		|| isCallOfFunctionNamed( iFn, "siglongjmp")) {
			print_error( fnDecl, "ENV32-C", "No atexit handler should terminate in any way other than by returning");
			violation = true;
		}
	}

	return violation;
}
예제 #2
0
파일: FIO.C 프로젝트: 8l/rose
/**
 * Take care when calling remove() on an open file
 */
bool FIO08_C( const SgNode *node ) {
	const SgFunctionRefExp *fnRef = isSgFunctionRefExp(node);
	if(!(fnRef && isCallOfFunctionNamed(fnRef, "remove")))
		return false;

	const SgExpression *fnExp = removeImplicitPromotions(getFnArg(fnRef,0));
	assert(fnExp);

	const SgVarRefExp *ref = isSgVarRefExp(fnExp);
	if(!ref)
		return false;
	const SgInitializedName *var = getRefDecl(ref);

	bool opened = false;
	bool closed = false;
	/* *open or *close */
	const SgFunctionRefExp *iFn = NULL;
	/* Argument to *open or *close */
	const SgVarRefExp *iVar = NULL;
	/* File descriptor return by *open */
	const SgInitializedName *fd = NULL;

	FOREACH_SUBNODE(findParentOfType(node, SgFunctionDefinition), nodes, i, V_SgFunctionRefExp) {
		iFn = isSgFunctionRefExp(*i);
		assert(iFn);

		if(iFn == fnRef)
			break;

		iVar = isSgVarRefExp(removeImplicitPromotions(getFnArg(iFn,0)));
		if (!iVar)
			continue;

		if(isCallOfFunctionNamed(iFn, "open")
		|| isCallOfFunctionNamed(iFn, "fopen")
		|| isCallOfFunctionNamed(iFn, "freopen")) {
			fd = getVarAssignedTo(iFn, NULL);
			assert(fd);

			if (getRefDecl(iVar) == var) {
				closed = false;
				opened = true;
			}
		}

		if (opened
		&& (isCallOfFunctionNamed(iFn, "close"))
		|| isCallOfFunctionNamed(iFn, "fclose")) {
			if (getRefDecl(iVar) == fd) {
				closed = true;
				opened = false;
			}
		}
	}
/*
 *  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);
      }
    }
  }
}
예제 #4
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.
예제 #5
0
파일: FIO.C 프로젝트: 8l/rose
/**
 * Prefer fseek() to rewind()
 */
bool FIO07_C( const SgNode *node ) {
	const SgFunctionRefExp *fnRef = isSgFunctionRefExp(node);
	if (!(fnRef && isCallOfFunctionNamed(fnRef, "rewind")))
		return false;
	print_error( node, "FIO07-C", "Prefer fseek() to rewind()", true);
	return true;
}
예제 #6
0
void
CompassAnalyses::NoVariadicFunctions::Traversal::
visit(SgNode* node)
   { 
     switch( node->variantT() )
     {
       case V_SgFunctionRefExp:
       {
         SgFunctionRefExp *fref = isSgFunctionRefExp(node);

         ROSE_ASSERT(fref != NULL);

         SgFunctionDeclaration *fdecl = fref->get_symbol()->get_declaration();

         this->functionDeclarationHandler(
           fdecl, fref );
       } break; //case V_SgFunctionRefExp
       case V_SgMemberFunctionRefExp:
       {
         SgMemberFunctionRefExp *fref = isSgMemberFunctionRefExp(node);

         ROSE_ASSERT(fref != NULL);

         SgFunctionDeclaration *fdecl = fref->get_symbol()->get_declaration();

         this->functionDeclarationHandler(
           fdecl, fref );
       } break; //case V_SgMemberFunctionRefExp
       default: break;
     } //switch( node->variantT() )

     return;
   } //End of the visit function.
예제 #7
0
파일: noExitInMpiCode.C 프로젝트: 8l/rose
/////////////////////////////////////////////////////////////////////////////////// The CompassAnalyses::NoExitInMpiCode::Traversal::visit(SgNode* node)
/// function implements a simple AST traversal seeking out SgFunctionRefExp
/// nodes for function reference expressions corresponding to MPI Init and
/// Finalize and calls to exit() nested in those blocks; these are reported
/// as checker violations.
///
/// \param node is a SgNode*
////////////////////////////////////////////////////////////////////////////////
void CompassAnalyses::NoExitInMpiCode::Traversal::visit(SgNode* node)
{
  static bool usedMPI = false;

  SgFunctionRefExp *sgfrexp = isSgFunctionRefExp(node);

  if( sgfrexp != NULL )
  {
    std::string sgfrexpName = sgfrexp->get_symbol()->get_name().getString();

    if( sgfrexpName == "MPI_Init" )
    {
      usedMPI = true;
    } //if( sgfrexpNam == "MPI_Init" )

    if( sgfrexpName == "MPI_Finalize" )
    {
      usedMPI = false;
    } //if( sgfrexpName == "MPI_Finalize" )

//#ASR:07/07/10
//fixed object creation of CheckerOutput for Cxx standard
    if( usedMPI == true && sgfrexpName == "exit" )
    {
      output->addOutput( new CompassAnalyses::NoExitInMpiCode::CheckerOutput( node ) );       
      //output->addOutput( new CompassAnalyses::NoExitInMpiCode::CheckerOutput::CheckerOutput( node ) );

    } //if( usedMPI == true && sgfrexpName == "exit" )

  } //if( sgfrexp != NULL )

  return;
} //visit(SgNode *node)
예제 #8
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.
예제 #9
0
파일: ENV.C 프로젝트: 8l/rose
/**
 * Do not use system()
 *
 * \note As written, these tests catch template declarations only if instantiated.
 */
bool ENV04_C( const SgNode *node ) {
	const SgFunctionRefExp *fnRef = isSgFunctionRefExp(node);
	if (!fnRef)
		return false;
	if (!(isCallOfFunctionNamed(fnRef, "system")
		||isCallOfFunctionNamed(fnRef, "popen")))
		return false;
	print_error( node, "ENV04-C", "Do not use system() or popen() unless you need a command interpreter", true);
	return true;
}
예제 #10
0
파일: ENV.C 프로젝트: 8l/rose
/**
 * Do not modify the string returned by getenv()
 */
bool ENV30_C( const SgNode *node ) {
	const SgFunctionRefExp *fnRef = isSgFunctionRefExp(node);
	if (!fnRef)
		return false;
	if (!isCallOfFunctionNamed(fnRef, "getenv"))
		return false;
	const SgInitializedName *var = getVarAssignedTo(fnRef, NULL);
	if (!var)
		return false;
	if (isConstType(var->get_type()->dereference()))
		return false;
	print_error(node, "ENV30-C", "Do not modify the string returned by getenv()");
	return true;
}
예제 #11
0
파일: aslanalysis.cpp 프로젝트: 8l/rose
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;
      
   }
}
예제 #12
0
파일: FIO.C 프로젝트: 8l/rose
/**
 * Be careful using functions that use file names for identification
 */
bool FIO01_C( const SgNode *node ) {
	const SgFunctionRefExp *fnRef = isSgFunctionRefExp(node);
	if (!fnRef)
		return false;
	if (!(isCallOfFunctionNamed(fnRef, "chown")
	|| isCallOfFunctionNamed(fnRef, "stat")
	|| isCallOfFunctionNamed(fnRef, "chmod"))) {
		return false;
	}

	const SgVarRefExp* file_name = isSgVarRefExp(getFnArg(fnRef,0));
	if (!file_name)
		return false;


	/**
	 * See if the file was opened inside this function, if so, we have a
	 * problem
	 */
	FOREACH_SUBNODE(findParentOfType(fnRef, SgFunctionDefinition), nodes, i, V_SgFunctionRefExp) {
		const SgFunctionRefExp *iFn = isSgFunctionRefExp(*i);
		assert(iFn);

		if (isCallOfFunctionNamed(iFn, "open")
		||  isCallOfFunctionNamed(iFn, "fopen")) {
			const SgVarRefExp *iVar = isSgVarRefExp(getFnArg(iFn,0));
			if (iVar && (getRefDecl(iVar) == getRefDecl(file_name))) {
				print_error(node, "FIO01-C", "Be careful using functions that use file names for identification", true);
				return true;
			}
		}
	}

	/* If the file was not opened, it's probably ok to use these functions */
	return false;
}
void FortranAnalysis::visit(SgFunctionCallExp * fcall)
{
   SgFunctionRefExp  * fref  = isSgFunctionRefExp(fcall->get_function());

   if (fref != NULL) {
      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);
         SgSymbol * sym = var->get_symbol();
         sym->setAttribute("halo_attr", new AstTextAttribute("HALO_VAR"));
         debug("SgFunctionCallExp: adding halo attribute to %s\n",
                sym->get_name().getString().c_str());
      }
   }
}
예제 #14
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:{}
			}
		}
예제 #15
0
파일: noRand.C 프로젝트: 8l/rose
void
CompassAnalyses::NoRand::Traversal::
visit(SgNode* node)
   {
     const int STRING_LEN_RAND = 4;

     SgFunctionRefExp *sgFuncRef = isSgFunctionRefExp( node );

     if( sgFuncRef != NULL )
     {
       std::string fncName = sgFuncRef->get_symbol()->get_name().getString();

       if( fncName.find( "rand", 0, STRING_LEN_RAND ) != std::string::npos )
       {
         output->addOutput( new CheckerOutput( node ) );
       } //if( fncName.find("vfork", 0, STRING_LEN_RAND) != std::string::npos )
     } //if( sgFuncRef != NULL )

     return;
   } //End of the visit function.
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;
}
예제 #17
0
파일: ENV.C 프로젝트: 8l/rose
/**
 * Beware of multiple environment variables with the same effective name
 */
bool ENV02_C( const SgNode *node ) {
	static std::set<std::string> origStrs;
	static std::set<std::string> normStrs;
	static std::map<std::string, const SgFunctionRefExp *> strToNode;

	const SgFunctionRefExp *fnRef = isSgFunctionRefExp(node);
	if (!fnRef)
		return false;

	if (!(isCallOfFunctionNamed(fnRef, "getenv")
		||isCallOfFunctionNamed(fnRef, "setenv")
		||isCallOfFunctionNamed(fnRef, "putenv"))) {
		return false;
	}
	const SgStringVal *strVal = isSgStringVal(removeImplicitPromotions(getFnArg(fnRef,0)));
	if (!strVal)
		return false;
	std::string str = strVal->get_value();
	if (const unsigned int eq = str.find_first_of("="))
		str = str.substr(0,eq);

	if (origStrs.find(str) != origStrs.end())
		return false;
	origStrs.insert(str);

	std::transform(str.begin(), str.end(), str.begin(), tolower);

	if (normStrs.find(str) != normStrs.end()) {
		print_error(node, "ENV02-C", "Beware of multiple environment variables with the same effective name", true);
		print_error(strToNode[str], "ENV02-C", "Previous reference was here", true);
		return true;
	}

	normStrs.insert(str);
	strToNode[str] = fnRef;
	return false;
}
예제 #18
0
파일: ENV.C 프로젝트: 8l/rose
/**
 * Do not rely on an environment pointer following an operation that may
 * invalidate it 
 */
bool ENV31_C( const SgNode *node ) {
	const SgVarRefExp *varRef = isSgVarRefExp(node);
	if (!varRef)
		return false;
	if (getRefDecl(varRef)->get_name().getString() != "envp")
		return false;
	bool violation = false;
	FOREACH_SUBNODE(getRefDecl(varRef)->get_scope(), nodes, i, V_SgExpression) {
		if (varRef == isSgVarRefExp(*i))
			break;
		const SgFunctionRefExp *iFn = isSgFunctionRefExp(*i);
		if (!iFn)
			continue;
		if (isCallOfFunctionNamed(iFn, "putenv")
		  ||isCallOfFunctionNamed(iFn, "setenv")) {
			violation = true;
			break;
		}
	}
	if (violation) {
		print_error(node, "ENV31-C", "Do not rely on an environment pointer following an operation that may invalidate it");
	}
	return violation;
}
SgFunctionDeclaration * 
getFunctionDeclaration(SgFunctionCallExp *functionCall) 
{ 
  SgFunctionDeclaration *funcDec = NULL; 

  SgExpression *expression = functionCall->get_function();
  ROSE_ASSERT(expression != NULL);

  switch(expression->variantT()) {
  case V_SgMemberFunctionRefExp:
    {
      SgMemberFunctionRefExp *memberFunctionRefExp =
	isSgMemberFunctionRefExp(expression);
      ROSE_ASSERT(memberFunctionRefExp != NULL);

      funcDec = memberFunctionRefExp->get_symbol_i()->get_declaration(); 

      ROSE_ASSERT(funcDec != NULL);

      break;
    }
  case V_SgDotExp:
    {
      SgDotExp *dotExp = isSgDotExp(expression);
      ROSE_ASSERT(dotExp != NULL);

      if(dotExp->get_traversalSuccessorContainer().size()>=2) { 

	SgMemberFunctionRefExp *memberFunctionRefExp = 
	  isSgMemberFunctionRefExp(dotExp->get_traversalSuccessorContainer()[1]); 
	funcDec = memberFunctionRefExp->get_symbol_i()->get_declaration(); 
      } 

      ROSE_ASSERT(funcDec != NULL);

      break;
    }
  case V_SgArrowExp:
    {
      SgArrowExp *arrowExp = isSgArrowExp(expression);
      ROSE_ASSERT(arrowExp != NULL);

      if(arrowExp->get_traversalSuccessorContainer().size()>=2) { 

	SgMemberFunctionRefExp *memberFunctionRefExp = 
	  isSgMemberFunctionRefExp(arrowExp->get_traversalSuccessorContainer()[1]); 
	funcDec = memberFunctionRefExp->get_symbol_i()->get_declaration(); 
      } 

      ROSE_ASSERT(funcDec != NULL);

      break;
    }
  case V_SgFunctionRefExp:
    {
      SgFunctionRefExp *functionRefExp = 
	isSgFunctionRefExp(expression);
      ROSE_ASSERT(functionRefExp != NULL);

      // found a standard function reference  
      funcDec = functionRefExp->get_symbol_i()->get_declaration(); 

      ROSE_ASSERT(funcDec != NULL);

      break;
    }
  case V_SgPointerDerefExp:
    {
      ROSE_ABORT();
      break;
    }
  default:
    {
      ROSE_ABORT();
    }
  }

  return funcDec; 
} 
예제 #20
0
파일: ENV.C 프로젝트: 8l/rose
/**
 * Do not store the pointer to the string returned by getenv()
 *
 * \todo Do we also need to check for putenv/setenv in the loop?
 */
bool ENV00_C( const SgNode *node ) {
	// find call of getenv
	const SgFunctionRefExp *fnRef = isSgFunctionRefExp(node);
	if (!fnRef)
		return false;
	if (!isCallOfFunctionNamed(fnRef, "getenv"))
		return false;
	// find var saved into
	const SgInitializedName *var = getVarAssignedTo(fnRef, NULL);
	if (!var)
		return false;
	bool getenv_found = false;
	bool write = false;
	bool after = false;

	// traverse down, searching for copy functions (break)
	FOREACH_SUBNODE(findParentOfType(fnRef, SgFunctionDefinition), nodes, i, V_SgExpression) {
		const SgExpression * expr = isSgExpression(*i);
		const SgFunctionRefExp *iFnRef = isSgFunctionRefExp(*i);
		assert(expr);
		if (!after) {
			if (iFnRef == fnRef)
				after = true;
			continue;
		}
		// search for another call to getenv
		if (iFnRef && isCallOfFunctionNamed(iFnRef, "getenv")) {
			getenv_found = true;
			if (var == getVarAssignedTo(isSgFunctionRefExp(expr), NULL))
				return false;
			continue;
		}
		if (!getenv_found)
			continue;

		// search for write (break)
		const SgVarRefExp *iVar = isSgVarRefExp(expr);
		if (!iVar || (getRefDecl(iVar) != var))
			continue;

		const SgFunctionCallExp *iFnCall = findParentOfType(iVar, SgFunctionCallExp);
		if (!iFnCall) {
			if (varWrittenTo(iVar))
				return false;
			write = true;
			break;
		}
		const SgFunctionRefExp *iFn = isSgFunctionRefExp(iFnCall->get_function());
		assert(iFn);
		if (isCallOfFunctionNamed(iFn, "strcpy")
		  ||isCallOfFunctionNamed(iFn, "memset")
		  ||isCallOfFunctionNamed(iFn, "strdup"))
			return false;
		write = true;
		break;
	}

	// if read & getenv then error
	if (getenv_found && write) {
		print_error(node, "ENV00-C", "Do not store the pointer to the string returned by getenv()", true);
		return true;
	}
	return false;
}
예제 #21
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);
   }