Example #1
0
void ExprWalker::visit(SgInitializedName* sgn)
{
  VariableId vid = vidm.variableId(sgn);
  
  // some SgInitializedName do not have symbols
  // VariableId is not created for such SgInitializedName
  // check and return if we are processing such SgInitializedName
  if(!vid.isValid()) {
    //cerr << "WARNING: Skipping SgInitializedName sgn->get_name() = " << sgn->get_name() << " with no symbol\n";
    return;
  }

  DefUseVarsInfo rduvi;
  SgInitializer* initializer = sgn->get_initializer();
  if(initializer) {
    rduvi = getDefUseVarsInfo_rec(initializer, vidm, false);
  }

  // SgInitializedName always define a variable
  // it should always be in def_set
  VarsInfo& def_vars_info = duvi.getDefVarsInfoMod();
  
  // determine the type info
  VariableIdTypeInfo sgn_type_info = getVariableIdTypeInfo(vid, vidm);

  if(vidm.getModeVariableIdForEachArrayElement() && sgn_type_info == arrayType)
    // When defining an array, define all its elements.
    duvi.addAllArrayElements(sgn, vidm, true);
  else
    def_vars_info.first.insert(VariableIdInfo(vid, sgn_type_info));

  duvi = duvi + rduvi;
}
VariableId VariableIdMapping::variableIdOfArrayElement(VariableId arrayVar, int elemIndex) {
  int idCode = arrayVar.getIdCode();
  int elemIdCode = idCode + elemIndex;
  VariableId elemVarId;
  elemVarId.setIdCode(elemIdCode);
  return elemVarId;
}
Example #3
0
// base case for the recursion
void SPRAY::ComputeAddressTakenInfo::OperandToVariableId::visit(SgVarRefExp *sgn)
{ 
  if(debuglevel > 0) debugPrint(sgn);
  VariableId id = cati.vidm.variableId(sgn);
  ROSE_ASSERT(id.isValid());
  // insert the id into VariableIdSet
  cati.addressTakenInfo.second.insert(id);
}
Example #4
0
/*! 
  * \author Markus Schordan
  * \date 2012.
 */
string VariableIdMapping::uniqueShortVariableName(VariableId varId) {
  if(!isTemporaryVariableId(varId)) {
    return variableName(varId)+"_"+varId.toString().substr(1);
    //return SgNodeHelper::uniqueLongVariableName(getSymbol(varId));
  } else {
    return string("tmp")+"_"+varId.toString().substr(1);
  }
}
/*! 
  * \author Markus Schordan
  * \date 2012.
 */
VariableIdMapping::VariableIdSet VariableIdMapping::getVariableIdSet() {
  VariableIdSet set;
  for(map<SgSymbol*,size_t>::iterator i=mappingSymToVarId.begin();i!=mappingSymToVarId.end();++i) {
    size_t t=(*i).second;
    VariableId id;
    id.setIdCode(t);
    set.insert(id);
  }
  return set;
}
// Returns a valid VariableId corresponding to *ref*
// if indices in *ref* are all integers and sizes of
// all array dimensions are known.
// Returns an invalid VariableId otherwise.
VariableId VariableIdMapping::idForArrayRef(SgPntrArrRefExp* ref)
{
  assert(ref);
  VariableId result;
  result.setIdCode(-1);

  // Check failure conditions
  if(isSgPntrArrRefExp(ref->get_parent()))
    return result;
  SgExpression* varRef;
  vector<SgExpression*> subscripts;
  vector<SgExpression*>* pSubscripts = &subscripts;
  SageInterface::isArrayReference(ref, &varRef, &pSubscripts);
  SgVarRefExp* arrVar = isSgVarRefExp(varRef);
  if(!arrVar)
    return result;
  SgArrayType* arrType = isSgArrayType(SageInterface::convertRefToInitializedName(arrVar)->get_type());
  if(!arrType)
    return result;
  vector<size_t> arrayDimensions;
  size_t arrSize = getArrayDimensions(arrType, &arrayDimensions);
  if(!arrSize) {
    arrayDimensions.clear();
    arrSize = getArrayDimensionsFromInitializer(
                isSgAggregateInitializer(SageInterface::convertRefToInitializedName(arrVar)->get_initializer()), 
                &arrayDimensions);
  }
  if(!arrSize)
    return result; // Array size is unknown
  assert(arrayDimensions.size() == subscripts.size());

  // Calculate the index as below.
  // int a[M][N][K];
  // a[x][y][z] => index = x*N*K + y*K + z.
  int index = 0;
  for(unsigned i = 0; i < subscripts.size(); i++) {
    int curIndex = exprToInt(subscripts[i]);
    if(curIndex == -1)
      return result;
    int dimension_size = (i == arrayDimensions.size() - 1 ? 1 : arrayDimensions[i + 1]);
    for(unsigned d = i + 2; d < arrayDimensions.size(); d++)
      dimension_size*= arrayDimensions[d];
    index += curIndex*dimension_size;
  }

  VariableId varId = variableId(arrVar);
  result = variableIdOfArrayElement(varId, index);
  return result;
}
Example #7
0
VariableValueRangeInfo VariableConstInfo::createVariableValueRangeInfo(VariableId varId, VarConstSetMap& map) {
    ROSE_ASSERT(map.size()>0);
    ROSE_ASSERT(varId.isValid());
    set<CppCapsuleConstIntLattice> cppCapsuleSet=map[varId];
    AType::ConstIntLattice minVal;
    AType::ConstIntLattice maxVal;
    // in case the set of collected assignments is empty, bot is returned (min and max remain bot).
    if(cppCapsuleSet.size()==0)
        return VariableValueRangeInfo(AType::ConstIntLattice(AType::Bot()));
    for(set<CppCapsuleConstIntLattice>::iterator i=cppCapsuleSet.begin(); i!=cppCapsuleSet.end(); ++i) {
        AType::ConstIntLattice aint=(*i).getValue();
        if(aint.isTop()) {
            return VariableValueRangeInfo(AType::ConstIntLattice(AType::Top()));
        }

        if(minVal.isBot() && maxVal.isBot()) {
            minVal=aint;
            maxVal=aint;
            continue;
        }
        if((aint<minVal).isTrue())
            minVal=aint;
        if((aint>maxVal).isTrue())
            maxVal=aint;
    }
    if(minVal.isBot()||maxVal.isBot())
        return VariableValueRangeInfo(AType::ConstIntLattice(AType::Bot()));
    return VariableValueRangeInfo(minVal,maxVal);
}
VariableIdMapping::VariableIdSet VariableIdMapping::variableIdsOfAstSubTree(SgNode* node) {
  VariableIdSet vset;
  RoseAst ast(node);
  for(RoseAst::iterator i=ast.begin();i!=ast.end();++i) {
    VariableId vid; // default creates intentionally an invalid id.
    if(SgVariableDeclaration* varDecl=isSgVariableDeclaration(*i)) {
      vid=variableId(varDecl);
    } else if(SgVarRefExp* varRefExp=isSgVarRefExp(*i)) {
      vid=variableId(varRefExp);
    } else if(SgInitializedName* initName=isSgInitializedName(*i)) {
      vid=variableId(initName);
    }
    if(vid.isValid())
      vset.insert(vid);
  }
  return vset;
}
Example #9
0
/*! 
  * \author Markus Schordan
  * \date 2013.
 */
void RDTransferFunctions::transferExpression(Label lab, SgExpression* node, Lattice& element0) {
  RDLattice* element1=dynamic_cast<RDLattice*>(&element0);
  ROSE_ASSERT(element1);
  RDLattice& element=*element1;
  // update analysis information
  // this is only correct for RERS12-C programs
  // 1) remove all pairs with lhs-variableid
  // 2) add (lab,lhs.varid)

  // (for programs with pointers we require a set here)
  VariableIdSet defVarIds=AnalysisAbstractionLayer::defVariables(node,*_variableIdMapping);  
  ROSE_ASSERT(_pointerAnalysisInterface);
  if(hasDereferenceOperation(node)) {
    VariableIdSet modVarIds=_pointerAnalysisInterface->getModByPointer();
    // union sets
    defVarIds+=modVarIds;
  }
  if(defVarIds.size()>1 /* TODO: || existsArrayVarId(defVarIds)*/ ) {
    // If an unknown array element is referenced, we consider
    // all its elements modified in the same statement.
    // Here *var* is an array element if its symbol is equal to at
    // least one of those corresponding to VariableIds with next or previous ids.
    for(VariableIdMapping::VariableIdSet::iterator i=defVarIds.begin();i!=defVarIds.end();++i) {
      VariableId var = *i;
      VariableId prev_var_id;
      VariableId next_var_id;
      prev_var_id.setIdCode(var.getIdCode() - 1);
      next_var_id.setIdCode(var.getIdCode() + 1);
      SgSymbol *var_smb = _variableIdMapping->getSymbol(var);
      SgSymbol *prev_var_smb = _variableIdMapping->getSymbol(prev_var_id);
      SgSymbol *next_var_smb = _variableIdMapping->getSymbol(next_var_id);
      if((var_smb == prev_var_smb) || (var_smb == next_var_smb))
        element.removeAllPairsWithVariableId(var);
    }
    // since multiple memory locations may be modified, we cannot know which one will be updated and can only add information
    for(VariableIdMapping::VariableIdSet::iterator i=defVarIds.begin();i!=defVarIds.end();++i) {
      element.insertPair(lab,*i);
    }
  } else if(defVarIds.size()==1) {
    // one unique memory location (variable). We can remove all pairs with this variable
    VariableId var=*defVarIds.begin();
    element.removeAllPairsWithVariableId(var);
    element.insertPair(lab,var);
  }
}
Example #10
0
//NOTE: missing: UD must take uses in initializers into account
void RDTransferFunctions::transferDeclaration(Label lab, SgVariableDeclaration* declnode, Lattice& element0) {
  RDLattice& element=dynamic_cast<RDLattice&>(element0);
  //  ROSE_ASSERT(element1);
  //RDLattice& element=*element1;

  SgInitializedName* node=SgNodeHelper::getInitializedNameOfVariableDeclaration(declnode);
  ROSE_ASSERT(node);
  // same as in transferExpression ... needs to be refined
  VariableIdSet defVarIds=AnalysisAbstractionLayer::defVariables(node,*_variableIdMapping);  
  if(defVarIds.size()>1 /* TODO: || existsArrayVarId(defVarIds)*/ ) {
    // If an array is defined, we add all its elements to def set.
    // Remove pairs corresponding to array elements as in transferExpression()
    // but now assert that only elements of one array were modified.
    unsigned elements = 0;
    SgSymbol *array_smb = _variableIdMapping->getSymbol(*(defVarIds.begin()));
    for(VariableIdMapping::VariableIdSet::iterator i=defVarIds.begin();i!=defVarIds.end();++i) {
      VariableId var = *i;
      VariableId prev_var_id;
      VariableId next_var_id;
      prev_var_id.setIdCode(var.getIdCode() - 1);
      next_var_id.setIdCode(var.getIdCode() + 1);
      SgSymbol *var_smb = _variableIdMapping->getSymbol(var);
      SgSymbol *prev_var_smb = _variableIdMapping->getSymbol(prev_var_id);
      SgSymbol *next_var_smb = _variableIdMapping->getSymbol(next_var_id);
      if((var_smb == prev_var_smb) || (var_smb == next_var_smb)) {
        element.removeAllPairsWithVariableId(var);
        elements++;
      }
      if(var_smb != array_smb)
        assert(0); // more than one array is modified
    }
    // since multiple memory locations may be modified, we cannot know which one will be updated and can only add information
    for(VariableIdMapping::VariableIdSet::iterator i=defVarIds.begin();i!=defVarIds.end();++i) {
      element.insertPair(lab,*i);
    }
    if(elements != defVarIds.size())
      assert(0);
  } else if(defVarIds.size()==1) {
    // one unique memory location (variable). We can remove all pairs with this variable
    VariableId var=*defVarIds.begin();
    element.removeAllPairsWithVariableId(var);
    element.insertPair(lab,var);
  }
}
Example #11
0
void ExprWalker::visit(SgVarRefExp* sgn)
{
  // get the VariableId
  VariableId vid = vidm.variableId(sgn);
  
  ROSE_ASSERT(vid.isValid());

  // determine type info
  VariableIdTypeInfo sgn_type_info = getVariableIdTypeInfo(vid, vidm); 

  VarsInfo& def_vars_info = duvi.getDefVarsInfoMod();
  VarsInfo& use_vars_info = duvi.getUseVarsInfoMod();

  if(isModExpr) {
    def_vars_info.first.insert(VariableIdInfo(vid, sgn_type_info));
  }
  else {
    use_vars_info.first.insert(VariableIdInfo(vid, sgn_type_info));
  }
}
Example #12
0
void ExprWalker::visit(SgVarRefExp* sgn)
{
  // get the VariableId
  VariableId vid = vidm.variableId(sgn);
  
  ROSE_ASSERT(vid.isValid());

  // determine type info
  VariableIdTypeInfo sgn_type_info = getVariableIdTypeInfo(vid, vidm); 

  VarsInfo& def_vars_info = duvi.getDefVarsInfoMod();
  VarsInfo& use_vars_info = duvi.getUseVarsInfoMod();

  if(vidm.getModeVariableIdForEachArrayElement() && sgn_type_info == arrayType) {
    // If found a reference to whole array, def/use all its elements.
    duvi.addAllArrayElements(SageInterface::convertRefToInitializedName(sgn), vidm, isModExpr);
  } else if(isModExpr) {
    def_vars_info.first.insert(VariableIdInfo(vid, sgn_type_info));
  } else {
    use_vars_info.first.insert(VariableIdInfo(vid, sgn_type_info));
  }
}
Example #13
0
list<SingleEvalResultConstInt> ExprAnalyzer::evalConstInt(SgNode* node,EState estate, bool useConstraints, bool safeConstraintPropagation) {
  assert(estate.pstate()); // ensure state exists
  SingleEvalResultConstInt res;
  //cout<<"DEBUG: evalConstInt: "<<node->unparseToString()<<astTermWithNullValuesToString(node)<<endl;
  // guard: for floating-point expression: return immediately with most general result
  // TODO: refine to walk the tree, when assignments are allowed in sub-expressions
  // MS: 2014-06-27: this cannot run in parallel because exp->get_type() seg-faults 
#if 0
  if(SgExpression* exp=isSgExpression(node)) {
    bool isFloatingPointType;
    // ROSE workaround. get_type cannot be run in parallel
    #pragma omp critical
    {
      isFloatingPointType=SgNodeHelper::isFloatingPointType(exp->get_type());
    }
    if(isFloatingPointType) {
      res.estate=estate;
      res.result=AType::ConstIntLattice(AType::Top());
      return listify(res);
    }
  }
#endif
  // initialize with default values from argument(s)
  res.estate=estate;
  res.result=AType::ConstIntLattice(AType::Bot());

  if(SgNodeHelper::isPostfixIncDecOp(node)) {
    cout << "Error: incdec-op not supported in conditions yet."<<endl;
    exit(1);
  }
  if(SgConditionalExp* condExp=isSgConditionalExp(node)) {
    list<SingleEvalResultConstInt> resultList;
    SgExpression* cond=condExp->get_conditional_exp();
    list<SingleEvalResultConstInt> condResultList=evalConstInt(cond,estate,useConstraints,safeConstraintPropagation);
    if(condResultList.size()==0) {
      cerr<<"Error: evaluating condition of conditional operator inside expressions gives no result."<<endl;
      exit(1);
    }
    if(condResultList.size()==2) {
      list<SingleEvalResultConstInt>::iterator i=condResultList.begin();
      SingleEvalResultConstInt singleResult1=*i;
      ++i;
      SingleEvalResultConstInt singleResult2=*i;
      if((singleResult1.value()==singleResult2.value()).isTrue()) {
        cout<<"Info: evaluating condition of conditional operator gives two equal results"<<endl;
      }
    }
    if(condResultList.size()>1) {
      cerr<<"Error: evaluating condition of conditional operator gives more than one result. Not supported yet."<<endl;
      exit(1);
    }
    SingleEvalResultConstInt singleResult=*condResultList.begin();
    if(singleResult.result.isTop()) {
      SgExpression* trueBranch=condExp->get_true_exp();
      list<SingleEvalResultConstInt> trueBranchResultList=evalConstInt(trueBranch,estate,useConstraints,safeConstraintPropagation);
      SgExpression* falseBranch=condExp->get_false_exp();
      list<SingleEvalResultConstInt> falseBranchResultList=evalConstInt(falseBranch,estate,useConstraints,safeConstraintPropagation);
      // append falseBranchResultList to trueBranchResultList (moves elements), O(1).
      trueBranchResultList.splice(trueBranchResultList.end(), falseBranchResultList); 
      return trueBranchResultList;
    }
    if(singleResult.result.isTrue()) {
      SgExpression* trueBranch=condExp->get_true_exp();
      list<SingleEvalResultConstInt> trueBranchResultList=evalConstInt(trueBranch,estate,useConstraints,safeConstraintPropagation);
      return trueBranchResultList;
    }
    if(singleResult.result.isFalse()) {
      SgExpression* falseBranch=condExp->get_false_exp();
      list<SingleEvalResultConstInt> falseBranchResultList=evalConstInt(falseBranch,estate,useConstraints,safeConstraintPropagation);
      return falseBranchResultList;
    }
    // dummy return value to avoid compiler warning
    cerr<<"Error: evaluating conditional operator inside expressions - unknown behavior (condition may have evaluated to bot)."<<endl;
    exit(1);
    return resultList;
  }
  if(dynamic_cast<SgBinaryOp*>(node)) {
    //cout << "BinaryOp:"<<SgNodeHelper::nodeToString(node)<<endl;

    SgNode* lhs=SgNodeHelper::getLhs(node);
    list<SingleEvalResultConstInt> lhsResultList=evalConstInt(lhs,estate,useConstraints,safeConstraintPropagation);
    SgNode* rhs=SgNodeHelper::getRhs(node);
    list<SingleEvalResultConstInt> rhsResultList=evalConstInt(rhs,estate,useConstraints,safeConstraintPropagation);
    //assert(lhsResultList.size()==1);
    //assert(rhsResultList.size()==1);
    list<SingleEvalResultConstInt> resultList;
    for(list<SingleEvalResultConstInt>::iterator liter=lhsResultList.begin();
        liter!=lhsResultList.end();
        ++liter) {
      for(list<SingleEvalResultConstInt>::iterator riter=rhsResultList.begin();
          riter!=rhsResultList.end();
          ++riter) {
        SingleEvalResultConstInt lhsResult=*liter;
        SingleEvalResultConstInt rhsResult=*riter;

        switch(node->variantT()) {
        case V_SgEqualityOp: {
          res.result=(lhsResult.result==rhsResult.result);
          res.exprConstraints=lhsResult.exprConstraints+rhsResult.exprConstraints;
          // record new constraint
          VariableId varId;
          if(variable(lhs,varId) && rhsResult.isConstInt()) {
            // if var is top add two states with opposing constraints
            if(!res.estate.pstate()->varIsConst(varId)) {
              SingleEvalResultConstInt tmpres1=res;
              SingleEvalResultConstInt tmpres2=res;
              tmpres1.exprConstraints.addConstraint(Constraint(Constraint::EQ_VAR_CONST,varId,rhsResult.value()));
              tmpres1.result=true;
              tmpres2.exprConstraints.addConstraint(Constraint(Constraint::NEQ_VAR_CONST,varId,rhsResult.value()));
              tmpres2.result=false;
              resultList.push_back(tmpres1);
              resultList.push_back(tmpres2);
              //return resultList; MS: removed 3/11/2014
              break;
            }
          }
          if(lhsResult.isConstInt() && variable(rhs,varId)) {
            // only add the equality constraint if no constant is bound to the respective variable
            if(!res.estate.pstate()->varIsConst(varId)) {
              SingleEvalResultConstInt tmpres1=res;
              SingleEvalResultConstInt tmpres2=res;
              tmpres1.exprConstraints.addConstraint(Constraint(Constraint::EQ_VAR_CONST,varId,lhsResult.value()));
              tmpres1.result=true;
              tmpres2.exprConstraints.addConstraint(Constraint(Constraint::NEQ_VAR_CONST,varId,lhsResult.value()));
              tmpres2.result=false;
              resultList.push_back(tmpres1);
              resultList.push_back(tmpres2);
              break;
            }
          }
          resultList.push_back(res);
          break;
        }
        case V_SgNotEqualOp: {
          res.result=(lhsResult.result!=rhsResult.result);
          res.exprConstraints=lhsResult.exprConstraints+rhsResult.exprConstraints;
          // record new constraint
          VariableId varId;
          if(variable(lhs,varId) && rhsResult.isConstInt()) {
            // only add the equality constraint if no constant is bound to the respective variable
            if(!res.estate.pstate()->varIsConst(varId)) {
              SingleEvalResultConstInt tmpres1=res;
              SingleEvalResultConstInt tmpres2=res;
              tmpres1.exprConstraints.addConstraint(Constraint(Constraint::NEQ_VAR_CONST,varId,rhsResult.value()));
              tmpres1.result=true;
              tmpres2.exprConstraints.addConstraint(Constraint(Constraint::EQ_VAR_CONST,varId,rhsResult.value()));
              tmpres2.result=false;
              resultList.push_back(tmpres1);
              resultList.push_back(tmpres2);
              break;
            }
          }
          if(lhsResult.isConstInt() && variable(rhs,varId)) {
            // only add the equality constraint if no constant is bound to the respective variable
            if(!res.estate.pstate()->varIsConst(varId)) {
              SingleEvalResultConstInt tmpres1=res;
              SingleEvalResultConstInt tmpres2=res;
              tmpres1.exprConstraints.addConstraint(Constraint(Constraint::NEQ_VAR_CONST,varId,lhsResult.value()));
              tmpres1.result=true;
              tmpres2.exprConstraints.addConstraint(Constraint(Constraint::EQ_VAR_CONST,varId,lhsResult.value()));
              tmpres2.result=false;
              resultList.push_back(tmpres1);
              resultList.push_back(tmpres2);
              break;
            }
          }
          resultList.push_back(res);
          break;
        }
        case V_SgAndOp: {
          //cout << "SgAndOp: "<<lhsResult.result.toString()<<"&&"<<rhsResult.result.toString()<<" ==> ";
          res.result=(lhsResult.result&&rhsResult.result);
          //cout << res.result.toString()<<endl;
#if 0
          cout << lhsResult.exprConstraints.toString();
          cout << "&&";
          cout << rhsResult.exprConstraints.toString();
          cout << " == > ";
#endif
          if(lhsResult.result.isFalse()) {
            res.exprConstraints=lhsResult.exprConstraints;
            // rhs is not considered due to short-circuit AND semantics
          }
          if(lhsResult.result.isTrue() && rhsResult.result.isFalse()) {
            res.exprConstraints=lhsResult.exprConstraints+rhsResult.exprConstraints;
            // nothing to do
          }
          if(lhsResult.result.isTrue() && rhsResult.result.isTrue()) {
            res.exprConstraints=lhsResult.exprConstraints+rhsResult.exprConstraints;
          }
          
          // in case of top we do not propagate constraints
          if(lhsResult.result.isTop() && !safeConstraintPropagation) {
            res.exprConstraints+=lhsResult.exprConstraints;
          }
          if(rhsResult.result.isTop() && !safeConstraintPropagation) {
            res.exprConstraints+=rhsResult.exprConstraints;
          }
          resultList.push_back(res);
          //          cout << res.exprConstraints.toString();
          //cout << endl;
          break;
        }
        case V_SgOrOp: {
          res.result=(lhsResult.result||rhsResult.result);
          // we encode short-circuit CPP-OR semantics here!
          if(lhsResult.result.isTrue()) {
            res.result=lhsResult.result;
            res.exprConstraints=lhsResult.exprConstraints;
          }
          if(lhsResult.result.isFalse() && rhsResult.result.isFalse()) {
            res.exprConstraints=lhsResult.exprConstraints+rhsResult.exprConstraints;
          }
          if(lhsResult.result.isFalse() && rhsResult.result.isTrue()) {
            res.exprConstraints=lhsResult.exprConstraints+rhsResult.exprConstraints;
          }
          // in case of top we do not propagate constraints
          if(lhsResult.result.isTop() && !safeConstraintPropagation) {
            res.exprConstraints+=lhsResult.exprConstraints;
          }
          if(rhsResult.result.isTop() && !safeConstraintPropagation) {
            res.exprConstraints+=rhsResult.exprConstraints;
          }
          resultList.push_back(res);
          break;
        }
        case V_SgAddOp: {
          res.result=(lhsResult.result+rhsResult.result);
          res.exprConstraints=lhsResult.exprConstraints+rhsResult.exprConstraints;
          resultList.push_back(res);
          break;
        }
        case V_SgSubtractOp: {
          res.result=(lhsResult.result-rhsResult.result);
          res.exprConstraints=lhsResult.exprConstraints+rhsResult.exprConstraints;
          resultList.push_back(res);
          break;
        }
        case V_SgMultiplyOp: {
          res.result=(lhsResult.result*rhsResult.result);
          res.exprConstraints=lhsResult.exprConstraints+rhsResult.exprConstraints;
          resultList.push_back(res);
          break;
        }
        case V_SgDivideOp: {
          res.result=(lhsResult.result/rhsResult.result);
          res.exprConstraints=lhsResult.exprConstraints+rhsResult.exprConstraints;
          resultList.push_back(res);
          break;
        }
        case V_SgModOp: {
          res.result=(lhsResult.result%rhsResult.result);
          res.exprConstraints=lhsResult.exprConstraints+rhsResult.exprConstraints;
          resultList.push_back(res);
          break;
        }
        case V_SgGreaterOrEqualOp: {
          res.result=(lhsResult.result>=rhsResult.result);
          if(boolOptions["relop-constraints"]) {
            if(res.result.isTop())
              throw "Error: Top found in relational operator (not supported yet).";
          }
          res.exprConstraints=lhsResult.exprConstraints+rhsResult.exprConstraints;
          resultList.push_back(res);
          break;
        }
        case V_SgGreaterThanOp: {
          res.result=(lhsResult.result>rhsResult.result);
          if(boolOptions["relop-constraints"]) {
            if(res.result.isTop())
              throw "Error: Top found in relational operator (not supported yet).";
          }
          res.exprConstraints=lhsResult.exprConstraints+rhsResult.exprConstraints;
          resultList.push_back(res);
          break;
        }
        case V_SgLessThanOp: {
          res.result=(lhsResult.result<rhsResult.result);
          if(boolOptions["relop-constraints"]) {
            if(res.result.isTop())
              throw "Error: Top found in relational operator (not supported yet).";
          }
          res.exprConstraints=lhsResult.exprConstraints+rhsResult.exprConstraints;
          resultList.push_back(res);
          break;
        }
        case V_SgLessOrEqualOp: {
          res.result=(lhsResult.result<=rhsResult.result);
          if(boolOptions["relop-constraints"]) {
            if(res.result.isTop())
              throw "Error: Top found in relational operator (not supported yet).";
          }
          res.exprConstraints=lhsResult.exprConstraints+rhsResult.exprConstraints;
          resultList.push_back(res);
          break;
        }
        case V_SgPntrArrRefExp: {
          // assume top for array elements (array elements are not stored in state)
          //cout<<"DEBUG: ARRAY-ACCESS2: ARR"<<node->unparseToString()<<"Index:"<<rhsResult.value()<<"skip:"<<getSkipArrayAccesses()<<endl;
          if(rhsResult.value().isTop()||getSkipArrayAccesses()==true) {
            res.result=AType::Top();
            res.exprConstraints=lhsResult.exprConstraints+rhsResult.exprConstraints;
            resultList.push_back(res);
            break;
          } else {
            if(SgVarRefExp* varRefExp=isSgVarRefExp(lhs)) {
              const PState* pstate=estate.pstate();
              PState pstate2=*pstate; // also removes constness
              VariableId arrayVarId=_variableIdMapping->variableId(varRefExp);
              // two cases
              if(_variableIdMapping->hasArrayType(arrayVarId)) {
                // has already correct id
                // nothing to do
              } else if(_variableIdMapping->hasPointerType(arrayVarId)) {
                // in case it is a pointer retrieve pointer value
                //cout<<"DEBUG: pointer-array access!"<<endl;
                if(pstate->varExists(arrayVarId)) {
                  AValue aValuePtr=pstate2[arrayVarId].getValue();
                  // convert integer to VariableId
                  int aValueInt=aValuePtr.getIntValue();
                  // change arrayVarId to refered array!
                  //cout<<"DEBUG: defering pointer-to-array: ptr:"<<_variableIdMapping->variableName(arrayVarId);
                  arrayVarId=_variableIdMapping->variableIdFromCode(aValueInt);
                  //cout<<" to "<<_variableIdMapping->variableName(arrayVarId)<<endl;//DEBUG
                } else {
                  cerr<<"Error: pointer variable does not exist in PState."<<endl;
                  exit(1);
                }
              } else {
                cerr<<"Error: unkown type of array or pointer."<<endl;
                exit(1);
              }
              VariableId arrayElementId;
              AValue aValue=rhsResult.value();
              if(aValue.isConstInt()) {
                int index=aValue.getIntValue();
                arrayElementId=_variableIdMapping->variableIdOfArrayElement(arrayVarId,index);
                //cout<<"DEBUG: arrayElementVarId:"<<arrayElementId.toString()<<":"<<_variableIdMapping->variableName(arrayVarId)<<" Index:"<<index<<endl;
              } else {
                cerr<<"Error: array index cannot be evaluated to a constant. Not supported yet."<<endl;
                cerr<<"expr: "<<varRefExp->unparseToString()<<endl;
                exit(1);
              }
              ROSE_ASSERT(arrayElementId.isValid());
              // read value of variable var id (same as for VarRefExp - TODO: reuse)
              if(pstate->varExists(arrayElementId)) {
                res.result=pstate2[arrayElementId].getValue();
                //cout<<"DEBUG: retrieved value:"<<res.result<<endl;
                if(res.result.isTop() && useConstraints) {
                  AType::ConstIntLattice val=res.estate.constraints()->varConstIntLatticeValue(arrayElementId);
                  res.result=val;
                }
                return listify(res);
              } else {
                cerr<<"Error: Array Element does not exist (out of array access?)"<<endl;
                cerr<<"array-element-id: "<<arrayElementId.toString()<<" name:"<<_variableIdMapping->variableName(arrayElementId)<<endl;
                cerr<<"PState: "<<pstate->toString(_variableIdMapping)<<endl;
                cerr<<"AST: "<<node->unparseToString()<<endl;
                exit(1);
              }
            } else {
              cerr<<"Error: array-access uses expr for denoting the array. Not supported yet."<<endl;
              cerr<<"expr: "<<lhs->unparseToString()<<endl;
              cerr<<"arraySkip: "<<getSkipArrayAccesses()<<endl;
              exit(1);
            }
          }
          break;
        }
        default:
            cerr << "Binary Op:"<<SgNodeHelper::nodeToString(node)<<"(nodetype:"<<node->class_name()<<")"<<endl;
          throw "Error: evalConstInt::unkown binary operation.";
        }
      }
    }
    return resultList;
  }
  
  if(dynamic_cast<SgUnaryOp*>(node)) {
    SgNode* child=SgNodeHelper::getFirstChild(node);
    list<SingleEvalResultConstInt> operandResultList=evalConstInt(child,estate,useConstraints,safeConstraintPropagation);
    //assert(operandResultList.size()==1);
    list<SingleEvalResultConstInt> resultList;
    for(list<SingleEvalResultConstInt>::iterator oiter=operandResultList.begin();
        oiter!=operandResultList.end();
        ++oiter) {
      SingleEvalResultConstInt operandResult=*oiter;
      switch(node->variantT()) {
      case V_SgNotOp:
        res.result=!operandResult.result;
        // we do NOT invert the constraints, instead we negate the operand result (TODO: investigate)
        res.exprConstraints=operandResult.exprConstraints;
        resultList.push_back(res);
      break;
      case V_SgCastExp: {
        // TODO: model effect of cast when sub language is extended
        //SgCastExp* castExp=isSgCastExp(node);
        res.result=operandResult.result;
        res.exprConstraints=operandResult.exprConstraints;
        resultList.push_back(res);
        break;
      }
        // unary minus
      case V_SgMinusOp: {
        res.result=-operandResult.result; // using overloaded operator
        res.exprConstraints=operandResult.exprConstraints;
        resultList.push_back(res);
        break;
      }
      default:
        cerr << "@NODE:"<<node->sage_class_name()<<endl;
        throw "Error: evalConstInt::unknown unary operation.";
      } // end switch
    }
    return  resultList;
  }
  
  ROSE_ASSERT(!dynamic_cast<SgBinaryOp*>(node) && !dynamic_cast<SgUnaryOp*>(node));
  
  // ALL REMAINING CASES DO NOT GENERATE CONSTRAINTS
  // EXPRESSION LEAF NODES
  switch(node->variantT()) {
  case V_SgBoolValExp: {
    SgBoolValExp* boolValExp=isSgBoolValExp(node);
    assert(boolValExp);
    int boolVal= boolValExp->get_value();
    if(boolVal==0) {
      res.result=false;
      return listify(res);
    }
    if(boolVal==1) {
      res.result=true;
      return listify(res);
    }
    break;
  }
  case V_SgDoubleVal: {
    //SgDoubleVal* doubleValNode=isSgDoubleVal(node);
    // floating point values are currently not computed
    res.result=AType::Top();
    return listify(res);
  }
  case V_SgIntVal: {
    SgIntVal* intValNode=isSgIntVal(node);
    int intVal=intValNode->get_value();
    res.result=intVal;
    return listify(res);
  }
  case V_SgVarRefExp: {
    VariableId varId;
    bool isVar=ExprAnalyzer::variable(node,varId);
    assert(isVar);
    const PState* pstate=estate.pstate();
    if(pstate->varExists(varId)) {
      PState pstate2=*pstate; // also removes constness

      if(_variableIdMapping->hasArrayType(varId)) {
        // CODE-POINT-1
        // for arrays (by default the address is used) return its pointer value (the var-id-code)
        res.result=AType::ConstIntLattice(varId.getIdCode());
      } else {
        res.result=pstate2[varId].getValue(); // this include assignment of pointer values
      }
      if(res.result.isTop() && useConstraints) {
        // in case of TOP we try to extract a possibly more precise value from the constraints
        AType::ConstIntLattice val=res.estate.constraints()->varConstIntLatticeValue(varId);
        // TODO: TOPIFY-MODE: most efficient here
        res.result=val;
      }
      return listify(res);
    } else {
      res.result=AType::Top();
      cerr << "WARNING: variable not in PState (var="<<_variableIdMapping->uniqueLongVariableName(varId)<<"). Initialized with top."<<endl;
      return listify(res);
    }
    break;
  }
  case V_SgFunctionCallExp: {
    if(getSkipSelectedFunctionCalls()) {
      // return default value
      return listify(res);
    } else {
      throw "Error: evalConstInt::function call inside expression.";
    }

  }

  default:
    cerr << "@NODE:"<<node->sage_class_name()<<endl;
    throw "Error: evalConstInt::unknown operation failed.";
  } // end of switch
  throw "Error: evalConstInt failed.";
}
/*! 
  * \author Markus Schordan
  * \date 2012.
 */
size_t SPRAY::hash_value(const VariableId& vid) {
  return vid.getIdCode();
}
/*! 
  * \author Markus Schordan
  * \date 2012.
 */
void VariableIdMapping::generateStmtSymbolDotEdge(std::ofstream& file, SgNode* node,VariableId id) {
  file<<"_"<<node<<" "
      <<"->"
      <<id.toString()
      << endl;
}
/*! 
  * \author Markus Schordan
  * \date 2012.
 */
VariableId VariableIdMapping::variableIdFromCode(int i) {
  VariableId id;
  id.setIdCode(i);
  return id;
}