Пример #1
0
void StaticConstructorTraversal::visit(SgNode *n) {

  // Get declared variables
  SgInitializedName *vName = isSgInitializedName(n);

  if (vName && !isAcreIgnore(vName->get_declaration())) {
    Sg_File_Info *fInfo = vName->get_file_info();
    SgScopeStatement *scope = vName->get_scope();
    
    // Find global variables (variables in namespaces count, e.g. std)
    if (!fInfo->isCompilerGenerated() && (isSgGlobal(scope) || isSgNamespaceDefinitionStatement(scope))) {

      // Walk typedefs until reach pointer to base type  
      SgTypedefType *tdType = isSgTypedefType(vName->get_type());
      while (tdType && isSgTypedefType(tdType->get_base_type())) 
        tdType = isSgTypedefType(tdType->get_base_type());
      
      // Determine if type is a class (i.e. type with a constructor)
      SgClassType *cType = isSgClassType(vName->get_type());
      if (tdType)
        cType = isSgClassType(tdType->get_base_type());
      
      // Output location of globals with a static constructor
      if (cType) {
        *out << "Static Constructor Violation: " << fInfo->get_filename() << " @ " << fInfo->get_line() << "\n";
      }
    }
  }
}
Пример #2
0
void
CompassAnalyses::StaticConstructorInitialization::Traversal::
visit(SgNode* node)
   { 
  // Test for static initialization of variables of type class, such initializations where they are 
  // static or appear in global scope can be called in an order dependent upon the compiler and this 
  // can lead to subtle bugs in large scale applications.

     SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(node);

     if (variableDeclaration != NULL)
        {
          SgInitializedNamePtrList::iterator i = variableDeclaration->get_variables().begin();
          while (i != variableDeclaration->get_variables().end())
             {
               SgInitializedName* initializedName = *i;

            // Check the type and see if it is a class (check for typedefs too)
               SgType* variableType = initializedName->get_type();

               SgClassType *classType = isSgClassType(variableType);
               if (classType != NULL)
                  {
                 // Now check if this is a global or namespace variable or an static class member
                 // This might also have to be a test for other scopes as well.
                    SgScopeStatement* scope = variableDeclaration->get_scope();
                    if (isSgGlobal(scope) != NULL || isSgNamespaceDefinitionStatement(scope) != NULL)
                       {
                      // printf ("Found a global variable defining a class = %p \n",initializedName);
                      // variableDeclaration->get_file_info()->display("global variable defining a class");
                         output->addOutput(new CheckerOutput(initializedName));
                       }

                    if (isSgClassDefinition(scope) != NULL)
                       {
                      // Now check if it is a static data member
                         if (variableDeclaration->get_declarationModifier().get_storageModifier().isStatic() == true)
                            {
                           // printf ("Found a static data member defining a class = %p \n",initializedName);
                           // variableDeclaration->get_file_info()->display("static data member defining a class");
                              output->addOutput(new CheckerOutput(initializedName));
                            }
                       }
                  }

            // increment though the variables in the declaration (typically just one)
               i++;
             }
        }

   } //End of the visit function.
Пример #3
0
void ModelBuilder::add(Model::model_t & model, SgVariableSymbol * variable_symbol) {
  SgScopeStatement * scope = variable_symbol->get_scope();
  assert(scope != NULL);

  SgNamespaceDefinitionStatement * nsp_defn     = isSgNamespaceDefinitionStatement(scope);
  SgClassDefinition              * class_defn   = isSgClassDefinition(scope);
  SgGlobal                       * global_scope = isSgGlobal(scope);
  
  SgType * sg_type = variable_symbol->get_type();
  assert(sg_type != NULL);
  Model::type_t type = model.lookup_type(sg_type);
  if (type == NULL) {
    add(model, sg_type);
    type = model.lookup_type(sg_type);
  }
  assert(type != NULL);
  
  if (nsp_defn != NULL || global_scope != NULL) {
    Model::variable_t element = Model::build<Model::e_model_variable>();

    element->node->symbol = variable_symbol;
    element->node->type = type;
  
    setParentFromScope<Model::e_model_variable>(model, element, variable_symbol);

    model.variables.push_back(element);
  }
  else if (class_defn != NULL) {
    Model::field_t element = Model::build<Model::e_model_field>();

    element->node->symbol = variable_symbol;
    element->node->type = type;
  
    setParentFromScope<Model::e_model_field>(model, element, variable_symbol);

    model.fields.push_back(element);
  }
  else {
    /// \todo error printing
    assert(false);
  }
}
Пример #4
0
bool Driver<Sage>::resolveValidParent<SgNamespaceSymbol>(SgNamespaceSymbol * symbol) {
  SgNamespaceSymbol * parent = NULL;
  
  if (p_valid_symbols.find(symbol) != p_valid_symbols.end()) return true;

  SgNamespaceDefinitionStatement * namespace_scope = isSgNamespaceDefinitionStatement(symbol->get_scope());
  if (namespace_scope != NULL) {
    SgNamespaceDeclarationStatement * parent_decl = namespace_scope->get_namespaceDeclaration();
    assert(parent_decl != NULL);
    parent = SageInterface::lookupNamespaceSymbolInParentScopes(parent_decl->get_name(), parent_decl->get_scope());
    assert(parent != NULL);

    if (!resolveValidParent<SgNamespaceSymbol>(parent)) return false;
    assert(p_valid_symbols.find(parent) != p_valid_symbols.end());
  }

  p_valid_symbols.insert(symbol);
  p_parent_map.insert(std::pair<SgSymbol *, SgSymbol *>(symbol, parent));
  p_namespace_symbols.insert(symbol);

  return true;
}
Пример #5
0
void
SgNamespaceDefinitionStatement::fixupCopy_symbols(SgNode* copy, SgCopyHelp & help) const
   {
#if DEBUG_FIXUP_COPY
     printf ("Inside of SgNamespaceDefinitionStatement::fixupCopy_symbols() for %p = %s copy = %p \n",this,this->class_name().c_str(),copy);
#endif
#if 0
     printf ("Inside of SgNamespaceDefinitionStatement::fixupCopy_symbols() for %p = %s copy = %p \n",this,this->class_name().c_str(),copy);
#endif
     SgNamespaceDefinitionStatement* namespaceDefinition_copy = isSgNamespaceDefinitionStatement(copy);
     ROSE_ASSERT(namespaceDefinition_copy != NULL);

     const SgDeclarationStatementPtrList & statementList_original = this->getDeclarationList();
     const SgDeclarationStatementPtrList & statementList_copy     = namespaceDefinition_copy->getDeclarationList();

     SgDeclarationStatementPtrList::const_iterator i_original = statementList_original.begin();
     SgDeclarationStatementPtrList::const_iterator i_copy     = statementList_copy.begin();

  // Iterate over both lists to match up the correct pairs of SgStatement objects
     while ( (i_original != statementList_original.end()) && (i_copy != statementList_copy.end()) )
        {
#if 0
          printf ("Inside of SgNamespaceDefinitionStatement::fixupCopy_symbols() for %p = %s copy = %p (in loop over statements) \n",this,this->class_name().c_str(),copy);
#endif
          (*i_original)->fixupCopy_symbols(*i_copy,help);

          i_original++;
          i_copy++;
        }
#if 0
     printf ("Leaving SgNamespaceDefinitionStatement::fixupCopy_symbols() for %p = %s copy = %p (call SgScopeStatement::fixupCopy_symbols()) \n",this,this->class_name().c_str(),copy);
#endif
  // Call the base class fixupCopy member function
     SgScopeStatement::fixupCopy_symbols(copy,help);
#if 0
     printf ("Leaving SgNamespaceDefinitionStatement::fixupCopy_symbols() for %p = %s copy = %p \n",this,this->class_name().c_str(),copy);
#endif
   }
Пример #6
0
void ModelBuilder::setParentFromScope(Model::model_t & model, Model::element_t<kind> * element, SgSymbol * symbol) {
  SgScopeStatement * scope = symbol->get_scope();
  assert(scope != NULL);

  SgNamespaceDefinitionStatement * nsp_defn     = isSgNamespaceDefinitionStatement(scope);
  SgClassDefinition              * class_defn   = isSgClassDefinition(scope);
  SgGlobal                       * global_scope = isSgGlobal(scope);

  if (nsp_defn != NULL) {
    // field and method cannot have namespace for scope
    assert(kind != Model::e_model_field && kind != Model::e_model_method);
  
    SgNamespaceDeclarationStatement * nsp_decl = nsp_defn->get_namespaceDeclaration();
    assert(nsp_decl != NULL);
    
    SgNamespaceSymbol * parent_symbol = isSgNamespaceSymbol(nsp_decl->get_symbol_from_symbol_table());
    assert(parent_symbol != NULL);
    
    Model::namespace_t parent_element = model.lookup_namespace(parent_symbol);
    if (parent_element == NULL) {
      add(model, parent_symbol);
      parent_element = model.lookup_namespace(parent_symbol);
    }
    assert(parent_element != NULL);
    
    switch (kind) {
      case Model::e_model_variable:  parent_element->scope->variable_children.push_back  ( (Model::variable_t)  element); break;
      case Model::e_model_function:  parent_element->scope->function_children.push_back  ( (Model::function_t)  element); break;
      case Model::e_model_type:      parent_element->scope->type_children.push_back      ( (Model::type_t)      element); break;
      case Model::e_model_class:     parent_element->scope->class_children.push_back     ( (Model::class_t)     element); break;
      case Model::e_model_namespace: parent_element->scope->namespace_children.push_back ( (Model::namespace_t) element); break;

      case Model::e_model_field:
      case Model::e_model_method:
        assert(false);
    }
    
    switch (kind) {
      case Model::e_model_variable:  ( (Model::variable_t)  element)->scope->parent = parent_element; break;
      case Model::e_model_function:  ( (Model::function_t)  element)->scope->parent = parent_element; break;
      case Model::e_model_namespace: ( (Model::namespace_t) element)->scope->parent = parent_element; break;

      case Model::e_model_type:  ( (Model::type_t)  element)->scope->parent.a_namespace = parent_element; break;
      case Model::e_model_class: ( (Model::class_t) element)->scope->parent.a_namespace = parent_element; break;

      case Model::e_model_field:
      case Model::e_model_method:
        assert(false);
    }
  }
  else if (class_defn != NULL) {
    // namespace, function, and variable cannot have class for scope
    assert(kind != Model::e_model_namespace && kind != Model::e_model_function && kind != Model::e_model_variable);
    
    SgClassDeclaration * class_decl = class_defn->get_declaration();
    assert(class_decl != NULL);
    
    SgClassSymbol * parent_symbol = isSgClassSymbol(class_decl->get_firstNondefiningDeclaration()->get_symbol_from_symbol_table());
    assert(parent_symbol != NULL);
    
    Model::class_t parent_element = model.lookup_class(parent_symbol);
    if (parent_element == NULL) {
      add(model, parent_symbol);
      parent_element = model.lookup_class(parent_symbol);
    }
    assert(parent_element != NULL);

    switch (kind) {
      case Model::e_model_field:  parent_element->scope->field_children.push_back  ( (Model::field_t)  element); break;
      case Model::e_model_method: parent_element->scope->method_children.push_back ( (Model::method_t) element); break;
      case Model::e_model_type:   parent_element->scope->type_children.push_back   ( (Model::type_t)   element); break;
      case Model::e_model_class:  parent_element->scope->class_children.push_back  ( (Model::class_t)  element); break;

      case Model::e_model_namespace:
      case Model::e_model_variable:
      case Model::e_model_function:
        assert(false);
    }

    switch (kind) {
      case Model::e_model_field:  ( (Model::field_t)  element)->scope->parent = parent_element; break;
      case Model::e_model_method: ( (Model::method_t) element)->scope->parent = parent_element; break;
      
      case Model::e_model_type:  ( (Model::type_t)  element)->scope->parent.a_class = parent_element; break;
      case Model::e_model_class: ( (Model::class_t) element)->scope->parent.a_class = parent_element; break;

      case Model::e_model_namespace:
      case Model::e_model_variable:
      case Model::e_model_function:
        assert(false);
    }
  }
  else if (global_scope != NULL) {
    /// \todo Should we have a root namespace to represent the global scope ???
  }
  else {
    /// \todo error printing
    assert(false);
  }
}
Пример #7
0
// GB (05/30/2007): This was completely rewritten from the old version to
// use much more efficient comparisons now available to us; it also never
// causes visits to included files, something that happened from time to
// time with the old version.
bool 
SgTreeTraversal_inFileToTraverse(SgNode* node, bool traversalConstraint, SgFile* fileToVisit)
   {
  // If traversing without constraint, just continue.
  // if (!traversalConstraint)
     if (traversalConstraint == false)
        {
          return true;
        }

#if 0
  // DQ (8/20/2018): Added debugging for support unparsing of header files.
     printf ("In SgTreeTraversal_inFileToTraverse(): fileToVisit = %p filename = %s \n",fileToVisit,fileToVisit->getFileName().c_str());
#endif

  // DQ (1/21/2008): Recently added SgAsmNodes for binaries also do not 
  // have a SgFileInfo object.
  // Of all the nodes to be traversed, only SgProject is allowed to have
  // a NULL file info; go ahead and try to traverse it (even though this
  // does not make sense since it is not within any file).
     if (node->get_file_info() == NULL)
        {
       // DQ (1/20/2008): This fails for binary files, why is this!
       // if (isSgProject(node) == NULL)
       //      printf ("What node is this: node = %p = %s \n",node,node->class_name().c_str()); // SageInterface::get_name(node).c_str());
       // ROSE_ASSERT(isSgProject(node) != NULL);

       // DQ (11/20/2013): Added SgJavaImportStatementList and SgJavaClassDeclarationList to the exception list since they don't have a source position field.
       // if (isSgProject(node) == NULL && isSgAsmNode(node) == NULL)
          if (isSgProject(node) == NULL && isSgAsmNode(node) == NULL && isSgJavaImportStatementList(node) == NULL && isSgJavaClassDeclarationList(node) == NULL)
          {
               printf ("Error: SgTreeTraversal_inFileToTraverse() --- node->get_file_info() == NULL: node = %p = %s \n",node,node->class_name().c_str());
               SageInterface::dumpInfo(node);
          }

#if 0
       // DQ (11/19/2013): Allow this to pass while we are evaluating the AST traversal for Java.
       // ROSE_ASSERT(isSgProject(node) != NULL || isSgAsmNode(node) != NULL);
       // if (isSgProject(node) == NULL && isSgAsmNode(node) == NULL)
          if (isSgProject(node) == NULL && isSgAsmNode(node) == NULL && isSgJavaImportStatementList(node) == NULL && isSgJavaClassDeclarationList(node) == NULL)
             {
               printf ("WARNING: isSgProject(node) == NULL && isSgAsmNode(node) == NULL: this could be Java code using an incomplete AST: node = %p = %s \n",node,node->class_name().c_str());
             }
#endif

          return true;
        }

  // Traverse compiler generated code and code generated from
  // transformations, unless it is "frontend specific" like the stuff in
  // rose_edg_required_macros_and_functions.h.
     bool isFrontendSpecific = node->get_file_info()->isFrontendSpecific();
     bool isCompilerGeneratedOrPartOfTransformation;
     if (isFrontendSpecific)
        {
          isCompilerGeneratedOrPartOfTransformation = false;
        }
       else
        {
       // DQ (11/14/2008): Implicitly defined functions in Fortran are not marked as compiler generated 
       // (the function body is at least explicit in the source file), but the function declaration IR 
       // nodes is marked as coming from file == NULL_FILE and it is also marked as "outputInCodeGeneration"
       // So it should be traversed so that we can see the function body and so that it can be a proper 
       // part of the definition of the AST.
       // isCompilerGeneratedOrPartOfTransformation = node->get_file_info()->isCompilerGenerated() || node->get_file_info()->isTransformation();
          bool isOutputInCodeGeneration = node->get_file_info()->isOutputInCodeGeneration();
          isCompilerGeneratedOrPartOfTransformation = node->get_file_info()->isCompilerGenerated() || node->get_file_info()->isTransformation() || isOutputInCodeGeneration;
        }

  // Traverse this node if it is in the file we want to visit.
     bool isRightFile = node->get_file_info()->isSameFile(fileToVisit);

#if 0
     printf ("In SgTreeTraversal_inFileToTraverse(): node = %p = %s isRightFile = %s \n",node,node->class_name().c_str(),isRightFile ? "true" : "false");
#endif

  // This function is meant to traverse input files in the sense of not
  // visiting "header" files (a fuzzy concept). But not every #included file
  // is a header, "code" (another fuzzy concept) can also be #included; see
  // test2005_157.C for an example. We want to traverse such code, so we
  // cannot rely on just comparing files.
  // The following heuristic is therefore used: If a node is included from
  // global scope or from within a namespace definition, we guess that it is
  // a header and don't traverse it. Otherwise, we guess that it is "code"
  // and do traverse it.
     bool isCode = node->get_parent() != NULL
                   && !isSgGlobal(node->get_parent())
                   && !isSgNamespaceDefinitionStatement(node->get_parent());

     bool traverseNode;
     if (isCompilerGeneratedOrPartOfTransformation || isRightFile || isCode)
          traverseNode = true;
       else
          traverseNode = false;


#if 0
  // DQ (8/17/2018): Need to stop here and debug this function tomorrow.
     printf ("Exiting as a test! \n");
     ROSE_ASSERT(false);
#endif

     return traverseNode;
   }