Exemplo n.º 1
0
int
main ( int argc, char* argv[] )
   {
  // Main Function for default example ROSE Preprocessor
  // This is an example of a preprocessor that can be built with ROSE
  // This example can be used to test the ROSE infrastructure

     ios::sync_with_stdio();     // Syncs C++ and C I/O subsystems!

     if (SgProject::get_verbose() > 0)
          printf ("In preprocessor.C: main() \n");

     SgProject* project = frontend(argc,argv);
     ROSE_ASSERT (project != NULL);

#if 0
  // This fails for test2005_63.C but Rich has fixed this
  // by updating the pdf library we are using within ROSE.
     printf ("Generate the pdf output of the SAGE III AST \n");
     generatePDF ( *project );
#endif

#if 0
     printf ("Generate the dot output of the SAGE III AST \n");
     generateDOT ( *project );
#endif

#if 1
  // DQ (2/6/2004): These tests fail in Coco for test2004_14.C
     AstTests::runAllTests(const_cast<SgProject*>(project));
#else
     printf ("Skipped agressive (slow) internal consistancy tests! \n");
#endif

     if (project->get_verbose() > 0)
          printf ("Calling the AST copy mechanism \n");

  // Demonstrate the copying of the whole AST
     SgProject* newProject = static_cast<SgProject*>(copyAST(project));
     ROSE_ASSERT(newProject != NULL);

     printf ("Running tests on copy of AST \n");
     AstTests::runAllTests(newProject);

     if (project->get_verbose() > 0)
          printf ("Calling the backend() \n");

     int errorCode = 0;
     errorCode = backend(project);

  // DQ (7/7/2005): Only output the performance report if verbose is set (greater than zero)
     if (project->get_verbose() > 0)
        {
       // Output any saved performance data (see ROSE/src/astDiagnostics/AstPerformance.h)
          AstPerformance::generateReport();
        }

  // printf ("Exiting with errorCode = %d \n",errorCode);
     return errorCode;
   }
Exemplo n.º 2
0
int
main ( int argc, char* argv[] )
   {
     ios::sync_with_stdio();     // Syncs C++ and C I/O subsystems!

     ofstream datfile ( "ProblemVariableDeclarations.data" , ios::out | ios::app );
     if ( datfile.good() == false )
        {
          printf ("File failed to open \n");
        }

  // datfile << "This is a test!" << std::endl;

#if 1
     SgProject* project = frontend(argc,argv);
     ROSE_ASSERT (project != NULL);

     Traversal traversal(&datfile);
     traversal.traverse(project,preorder);
#endif

     datfile.close();

#if 1
  // Run AST consistancy tests (so that we can test them while we analize KULL
     AstTests::runAllTests(const_cast<SgProject*>(project));
#else
     printf ("Skipped agressive (slow) internal consistancy tests! \n");
#endif



#if 0
     return 0;
#else
  // Output the source code and generate the object file so that 
  // we can test these parts of KULL processing as well
     if (project->get_verbose() > 0)
          printf ("Calling the backend() \n");

     int errorCode = 0;
     errorCode = backend(project);

  // DQ (12/3/2004): Test use of AST delete
  // DeleteSgTree(project);
     project = NULL;

  // DQ (7/7/2005): Only output the performance report if verbose is set (greater than zero)
     if (project->get_verbose() > 0)
        {
       // Output any saved performance data (see ROSE/src/astDiagnostics/AstPerformance.h)
          AstPerformance::generateReport();
        }
     return errorCode;
#endif

   }
int
main ( int argc, char* argv[] )
   {
  // DQ (7/7/2005): Introduce tracking of performance of ROSE.
     TimingPerformance timer ("AST check Main:");

     SgProject* project = frontend(argc,argv);
     ROSE_ASSERT (project != NULL);

     findSwitchWithoutDefault(project);

  // if (project->get_verbose() > 0)
  //      printf ("Calling the backend() \n");

     int errorCode = 0;
  // errorCode = backend(project);

  // Just set the project, the report will be generated upon calling the destructor for "timer"
     timer.set_project(project);

     if (project->get_verbose() > 0)
        {
       // Output any saved performance data (see ROSE/src/astDiagnostics/AstPerformance.h)
          AstPerformance::generateReport();
        }

  // return 0;
  // printf ("Exiting with errorCode = %d \n",errorCode);
     return errorCode;
   }
Exemplo n.º 4
0
int
main( int argc, char * argv[] )
   {
  // Introduces tracking of performance of ROSE at the top most level.
     TimingPerformance timer ("AST translation (main): time (sec) = ",true);

     SgProject* project = frontend(argc,argv);

     AstTests::runAllTests(project);

  // Output statistics about how ROSE was used...
     if (project->get_verbose() > 1)
        {
          std::cout << AstNodeStatistics::traversalStatistics(project);
          std::cout << AstNodeStatistics::IRnodeUsageStatistics();
        }

  // Just set the project, the report will be generated upon calling the destructor for "timer"
  // Use option "-rose:verbose 2" to see the report.
     timer.set_project(project);

  // Skip calling the typical backend for ROSE (not required for just testing analysis)
  // This backend calls the backend compiler using the original input source file list.
     return backendCompilesUsingOriginalInputFile(project);
   }
int
main ( int argc, char* argv[] )
   {
     ROSE_INITIALIZE;

     if (SgProject::get_verbose() > 0)
          printf ("In preprocessor.C: main() \n");

     SgProject* project = frontend(argc,argv);
     ROSE_ASSERT (project != NULL);

     Rose_STL_Container<SgNode*> nodeList;
     nodeList = NodeQuery::querySubTree (project,V_SgForStatement);
     printf ("\nnodeList.size() = %zu \n",nodeList.size());

     Rose_STL_Container<SgNode*>::iterator i = nodeList.begin();
     while (i != nodeList.end())
        {
          Sg_File_Info & fileInfo = *((*i)->get_file_info());
          printf ("Query node = %p = %s in %s \n ----- at line %d on column %d \n",
              *i,(*i)->sage_class_name(),fileInfo.get_filename(),
               fileInfo.get_line(), fileInfo.get_col());
          i++;
        }

     if (project->get_verbose() > 0)
          printf ("Calling the backend() \n");

     return 0;
   }
Exemplo n.º 6
0
int
main( int argc, char * argv[] )
   {
  // Introduces tracking of performance of ROSE at the top most level.
     TimingPerformance timer ("AST translation (main): time (sec) = ",true);

  // Build a vector of strings to represent the command line arguments.
     std::vector<std::string> sourceCommandline = std::vector<std::string>(argv, argv + argc);
     sourceCommandline.push_back("-rose:unparse_tokens");

     SgProject* project = frontend(sourceCommandline);

     AstTests::runAllTests(project);

  // Evaluate the number of tokens generated for each file on the command line.
     SgFilePtrList & fileList = project->get_fileList();
     for (size_t i=0; i < fileList.size(); i++)
        {
          SgSourceFile* sourceFile = isSgSourceFile(fileList[i]);
          if (sourceFile != NULL)
             {
               size_t numberOfTokens = sourceFile->get_token_list().size();
               printf ("Number of tokens in file %s = %zu \n",sourceFile->get_sourceFileNameWithPath().c_str(),numberOfTokens);
               if (numberOfTokens == 0)
                  {
                 // We output an error, but since this test is only presently valid for fortran files it is not serious.
                    if (sourceFile->get_Fortran_only() == true)
                       {
                         printf ("Warning: numberOfTokens in file equal zero (could be an error). \n");
                       }
                      else
                       {
                         printf ("Warning: token evaluation only valid for Fortran files at present. \n");
                       }
                  }
             }
            else
             {
               printf ("Warning, token evaluation only valid for source files. \n");
             }
        }

  // Output statistics about how ROSE was used...
     if (project->get_verbose() > 1)
        {
          std::cout << AstNodeStatistics::traversalStatistics(project);
          std::cout << AstNodeStatistics::IRnodeUsageStatistics();
        }

  // Just set the project, the report will be generated upon calling the destructor for "timer"
  // Use option "-rose:verbose 2" to see the report.
     timer.set_project(project);

  // Skip calling the typical backend for ROSE (not required for just testing analysis)
  // This backend calls the backend compiler using the original input source file list.
     return backendCompilesUsingOriginalInputFile(project);
   }
int
main ( int argc, char* argv[] )
   {
     ios::sync_with_stdio();     // Syncs C++ and C I/O subsystems!

     if (SgProject::get_verbose() > 0)
          printf ("In preprocessor.C: main() \n");

     SgProject* project = frontend(argc,argv);
     ROSE_ASSERT (project != NULL);

  // AST diagnostic tests
     AstTests::runAllTests(const_cast<SgProject*>(project));

  // test statistics
     if (project->get_verbose() > 1)
        {
          cout << AstNodeStatistics::traversalStatistics(project);
          cout << AstNodeStatistics::IRnodeUsageStatistics();
        }

     if (project->get_verbose() > 0)
          printf ("Generate the pdf output of the SAGE III AST \n");
     generatePDF ( *project );

     if (project->get_verbose() > 0)
          printf ("Generate the DOT output of the SAGE III AST \n");
     generateDOT ( *project );

     Rose_STL_Container<SgNode*> nodeList;
  // nodeList = NodeQuery::querySubTree (project,V_SgType,NodeQuery::ExtractTypes);
     nodeList = NodeQuery::querySubTree (project,V_SgForStatement);
     printf ("\nnodeList.size() = %zu \n",nodeList.size());

     Rose_STL_Container<SgNode*>::iterator i = nodeList.begin();
     while (i != nodeList.end())
        {
          printf ("Query node = %p = %s = %s \n",*i,(*i)->sage_class_name(),(*i)->unparseToString().c_str());
          i++;
        }

     return 0;
   }
static void
run(Compass::Parameters parameters, Compass::OutputObject* output)
{


  // We only care about source code in the user's space, not,
  // for example, Boost or system files.
  string target_directory =
      parameters["general::target_directory"].front();
  CompassAnalyses::AllocateAndFreeInTheSameModule::source_directory.assign(target_directory);

  // Use the pre-built ROSE AST
  SgProject* sageProject = Compass::projectPrerequisite.getProject();
  ROSE_ASSERT(sageProject != NULL);

  SgNode* root_node = (SgNode*) sageProject;
  ROSE_ASSERT(root_node != NULL);

  bool verbose = sageProject->get_verbose();

  // maps variables in the symbol table to a boolean
  // determining whether that variable has been freed
  // or not
  boost::unordered_map<SgSymbol*, bool> var_free_status;

  // maps variables in the symbol table to the original malloc
  // call that was performed on them so we can return this
  // as checker output if no matching frees are found
  boost::unordered_map<SgSymbol*, SgNode*> malloc_nodes;

  // keeps track of the dynamically allocated variables in the
  // symbol table that were freed
  boost::unordered_set<SgSymbol*> freed;

  // keeps track of the dynamically allocated variables in the
  // symbol table
  std::vector<SgSymbol*> unfreed;

  // tracks function calls that explicitly return a malloc (e.g. return malloc()...)
  boost::unordered_set<SgFunctionCallExp*> explicit_malloc_func_calls;

  // keeps track of the inner variable being returned by a pointer function
  // e.g. return var1; appearing in the function func1 would map func1 to var1
  boost::unordered_map<SgFunctionCallExp*, SgSymbol*> func_inner_var_mappings;

  // keeps track of the outer variable that receives the value of a pointer function
  // e.g. var2 = func1(); would map func1 to var2
  boost::unordered_map<SgFunctionCallExp*, SgSymbol*> func_outer_var_mappings;

  // keeps a list of all functions added to either of the above two hash maps
  boost::unordered_set<SgFunctionCallExp*> tracked_functions;


  // for each pointer variable, tracks the list of all other pointer
  // variables in the program that are ever set to the value (and are thus
  // associated with) this pointer variable
  boost::unordered_map<SgSymbol*, boost::unordered_set<SgSymbol*> > var_mappings;
  std::vector<SgSymbol*> var_mappings_list;

  VariableIdMapping var_ids;
  var_ids.computeVariableSymbolMapping(sageProject);

  // we have to do SgFunctionCallExp's first because the inner/outer
  // variable mappings require this to be pre-processed
  AstMatching func_call_matcher;
  MatchResult func_call_matches = func_call_matcher
      .performMatching("$f=SgFunctionCallExp", root_node);
  BOOST_FOREACH(SingleMatchVarBindings match, func_call_matches)
  {
    SgFunctionCallExp *func_call = (SgFunctionCallExp *)match["$f"];
    SgFunctionRefExp *func_ref = isSgFunctionRefExp(func_call->get_traversalSuccessorByIndex(0));
    if(func_ref == NULL) continue;
    std::string func_str = func_ref->get_symbol()->get_name().getString();
    if(func_str.compare("free") == 0)
    {
      AstMatching var_matcher;
      SgVarRefExp *var_ref = isSgVarRefExp(var_matcher
                                           .performMatching("$r=SgVarRefExp", func_call)
                                           .back()["$r"]);
      if(var_ref)
      {
        SgSymbol *var_ref_symbol = var_ref->get_symbol();
        if(verbose)
          std::cout << "FREE FOUND ON: " << var_ref_symbol->get_name() << std::endl;
        freed.insert(var_ref_symbol);
      }
    } else {

      SgExprListExp *expr_list = func_call->get_args();
      SgFunctionDefinition *func_def = SgNodeHelper::determineFunctionDefinition(func_call);
      if(func_def == NULL) continue;
      SgFunctionDeclaration *func_dec = func_def->get_declaration();
      if(func_dec == NULL) continue;
      SgFunctionParameterList *func_params = func_dec->get_parameterList();
      if(func_params == NULL) continue;
      for(int i = 0; i < expr_list->get_numberOfTraversalSuccessors(); i++)
      {
        if(i >= func_params->get_numberOfTraversalSuccessors()) break;
        SgNode* param = expr_list->get_traversalSuccessorByIndex(i);
        SgInitializedName* func_param =
            isSgInitializedName(func_params->get_traversalSuccessorByIndex(i));

        VariableId func_param_id = var_ids.variableId(func_param);
        SgSymbol *func_param_sym = var_ids.getSymbol(func_param_id);

        ROSE_ASSERT(func_param != NULL);
        ROSE_ASSERT(func_param_sym != NULL);

        // we use an AST match in case this is a container type
        // the last match will be a reference to the actual variable
        SgVarRefExp *param_var = NULL;
        AstMatching param_var_matcher;
        MatchResult param_var_matches = param_var_matcher
            .performMatching("$v=SgVarRefExp", param);
        if(param_var_matches.size() > 0)
        {
          param_var = (SgVarRefExp *)param_var_matches.back()["$v"];
        }
        if(param_var != NULL)
        {
          SgSymbol *param_sym = param_var->get_symbol();
          // now we must add var mappings from the inner parameter of the function

          if(var_mappings.find(param_sym) == var_mappings.end())
          {
            var_mappings_list.push_back(param_sym);
            boost::unordered_set<SgSymbol*> set;
            set.insert(func_param_sym);
            var_mappings[param_sym] = set;
          } else {
            var_mappings[param_sym].insert(func_param_sym);
          }

        } else {
          // handle the case of malloc() or calloc() being passed as a function parameter
          AstMatching func_ref_matcher;
          MatchResult found_func_matches =
              func_ref_matcher.performMatching("$r=SgFunctionRefExp", param);
          if(found_func_matches.size() > 0)
          {
            SgFunctionRefExp *found_func = isSgFunctionRefExp(
                found_func_matches.front()["$r"]);
            if(!found_func->isDefinable()) continue;
            std::string found_func_str = found_func->get_symbol()
                                             ->get_name().getString();
            if(found_func_str.compare("malloc") == 0
                || found_func_str.compare("calloc") == 0)
            {
              // found a malloc call within a function parameter
              // we must map this to whatever variable it would be assigned in the
              // parent function
              var_free_status[func_param_sym] = false;
              malloc_nodes[func_param_sym] = found_func->get_symbol();
              unfreed.push_back(func_param_sym);
            }
          }
        }
      }

      // figure out if a malloc is returned (directly) by this function
      AstMatching return_matcher;
      MatchResult return_matches = return_matcher
          .performMatching("$r=SgReturnStmt", func_def);
      BOOST_FOREACH(SingleMatchVarBindings return_match, return_matches)
      {
        SgReturnStmt *func_ret = (SgReturnStmt *)return_match["$r"];

        // map MALLOCS & CALLOC out
        AstMatching return_func_matcher;
        MatchResult return_func_matches = return_func_matcher
            .performMatching("$f=SgFunctionRefExp", func_ret);
        BOOST_FOREACH(SingleMatchVarBindings return_func_match, return_func_matches)
        {
          SgFunctionRefExp *return_func_ref = (SgFunctionRefExp *)return_func_match["$f"];
          SgFunctionCallExp *return_func_call = isSgFunctionCallExp(return_func_ref->get_parent());
          if(return_func_call == NULL) continue;
          std::string return_func_str = return_func_ref->get_symbol()->get_name().getString();

          if(return_func_str.compare("malloc") == 0 || return_func_str.compare("calloc") == 0)
          {
            if(verbose && explicit_malloc_func_calls.find(func_call)
                == explicit_malloc_func_calls.end())
            {
              std::cout << "MALLOC FOUND ON: \"" << func_str << "\" return statement" << std::endl;
            }
            explicit_malloc_func_calls.insert(func_call);
            // once we have one malloc we can ignore the rest of the return statement
            break;
          }
        }

        // do inner var mappings
        AstMatching return_var_matcher;
        MatchResult return_var_matches = return_var_matcher
            .performMatching("$v=SgVarRefExp", func_ret);
        BOOST_FOREACH(SingleMatchVarBindings return_var_match, return_var_matches)
        {
          SgVarRefExp *return_var = (SgVarRefExp *)return_var_match["$v"];
          // skip non pointer variables
          if(!SageInterface::isPointerType(return_var->get_type())) continue;
          SgSymbol *return_var_sym = return_var->get_symbol();
          if(return_var_sym == NULL) continue;
          func_inner_var_mappings[func_call] = return_var_sym;
          tracked_functions.insert(func_call);
          if(verbose)
            std::cout << "INNER VARIABLE MAPPING: " << func_str << " returns " << return_var_sym->get_name() << std::endl;
        }