예제 #1
0
void PtrAnal::
ProcessMod(AstInterface& fa, const std::string& readname, 
          std::list<std::string>& fields, const AstNodePtr& mod)
{
  std::string modname;
  AstNodePtr p = mod;
  if (fa.IsVarRef(mod) || fa.IsArrayAccess(mod, &p)) {
      modname = Get_VarName(fa,p);
      Stmt stmt_last = fields.size()?
                      field_x_eq_y(modname, fields, readname)
                     : x_eq_y(modname, readname);
      stmts_pushback(stmts,stmt_last);
      namemap[mod.get_ptr()] = VarRef(stmt_last,modname);
  }
  else {
     AstInterface::OperatorEnum op;
     AstNodePtr p2;
     if (fa.IsUnaryOp(mod,&op, &p) && op == AstInterface::UOP_DEREF) {
            std::string lhs = Get_VarName(fa,p); 
            Stmt stmt_last  = deref_x_eq_y(lhs, fields, readname); 
            stmts_pushback(stmts,stmt_last);
            namemap[p.get_ptr()] = VarRef(stmt_last,lhs);
            namemap[mod.get_ptr()] = VarRef(stmt_last, readname);
     }
    else if (fa.IsBinaryOp(mod,&op,&p,&p2)) { 
         if (op==AstInterface::BOP_DOT_ACCESS) {
            std::string field = Local_GetFieldName(fa, p2);
            fields.push_front(field);
            ProcessMod(fa, readname, fields, p);
            Stmt stmt_last = stmts_back(stmts);
            namemap[mod.get_ptr()] = VarRef(stmt_last, readname);
         }
         else if (op==AstInterface::BOP_ARROW_ACCESS) {
            std::string lhs = Get_VarName(fa, p), field = Local_GetFieldName(fa, p2);
            fields.push_front(field);
            Stmt stmt_last  = deref_x_eq_y(lhs,fields,readname);
            stmts_pushback(stmts,stmt_last);
            namemap[p.get_ptr()] = VarRef(stmt_last,lhs);
            namemap[mod.get_ptr()] = VarRef(stmt_last, readname);
         }
         else {
            std::cerr << "can't handle " << AstToString(mod) << "\n";
            assert(false); // other operations? to be handled later  
         }
     }
     else if (fa.IsFunctionCall(mod)) {
         std::string lhs = Get_VarName(fa, mod);
         Stmt stmt_last = deref_x_eq_y(lhs, fields, readname);
         stmts_pushback(stmts,stmt_last);
         namemap[mod.get_ptr()] = VarRef(stmt_last,lhs);
     }
     else {
       std::cerr << "cannot process " << AstToString(mod) << "\n";
       assert(false); // other operations? to be handled later  
    }
  }
}
예제 #2
0
std::string PtrAnal:: 
Get_VarName(AstInterface& fa, const AstNodePtr& rhs)
{
  NameMap::const_iterator p = namemap.find(rhs.get_ptr());
  if (p != namemap.end()) {
     VarRef cur = (*p).second;
     return cur.name;
  }

   std::string readname, res;
   AstNodePtr readscope; 
   AstNodePtr lhs1, rhs1;
   bool readlhs;

   if (fa.IsVarRef(rhs, 0, &readname, &readscope))  {
       assert(readname != "");
       res = Local_GetVarName(fa, readscope, readname); 
    }
   else if (fa.IsConstant(rhs,&res,&readname)) {
      if (res == "string") {
         readname =  Local_GetVarName(fa, rhs);
         Stmt stmt = allocate_x(readname);
         stmts_pushback(stmts,stmt);
         res= readname;
      }
      else
         res = Local_GetConstName(fa, readname);
   }
   else if (fa.IsUnaryOp(rhs) || fa.IsBinaryOp(rhs) || fa.IsFunctionCall(rhs)) {
        readname = Local_GetVarName(fa, rhs);
        ProcessExpression(fa, readname, rhs);
        res = readname;
   }
   else if (fa.IsAssignment(rhs,&lhs1,&rhs1,&readlhs)) {
        ProcessAssign(fa, lhs1, rhs1, readlhs);
        VarRef cur = namemap[lhs1.get_ptr()];
        if (cur.name == "") {
           std::cerr << "does not have map for " << AstToString(lhs1) << " in " << AstToString(rhs) << "\n";
           assert(0);
        }
        namemap[rhs.get_ptr()] = cur;
        res = cur.name;
   }
   else  {
      std::cerr << "No name found for " << AstToString(rhs) << "\n";
      assert(false);
   }
   if (res == "") {
      std::cerr << "No name found for " << AstToString(rhs) << "\n";
      assert(false);
   }
   return res;
}
예제 #3
0
bool ArrayUseAccessFunction::get_modify(AstInterface& fa, const AstNodePtr& fc,
                               CollectObject<AstNodePtr>* collect)
{
  AstInterface::AstNodeList args;
  if (prev1 != 0 && prev1->get_modify(fa, fc, collect))
       return true;
  std::string sig;
  AstNodePtr f;
  if (fa.IsFunctionCall(fc, &f,&args) && fa.IsVarRef(f,0,&sig) && sig == funcname) {
       return true;
  }
  return false;
}
예제 #4
0
bool ArrayUseAccessFunction::get_read(AstInterface& fa, const AstNodePtr& fc,
                               CollectObject<AstNodePtr>* collect)
{
  AstInterface::AstNodeList args;
  if (prev1 != 0 && prev1->get_read(fa, fc, collect))
       return true;
  std::string sig;
  AstNodePtr f;
  if (fa.IsFunctionCall(fc, &f,&args) && fa.IsVarRef(f,0,&sig) && sig == funcname) {
       if (collect != 0)  {
           AstInterface::AstNodeList::const_iterator argp = args.begin();
           for ( ++argp; argp != args.end(); ++argp) {
              (*collect)(*argp);
           }
       }
       return true;
  }
  return false;
}
예제 #5
0
bool ArrayUseAccessFunction::
IsArrayAccess( AstInterface& fa, const AstNodePtr& s, AstNodePtr* array, 
                                 AstInterface::AstNodeList* index) 
{
  AstInterface::AstNodeList args;
  if (prev != 0 &&  prev->IsArrayAccess(fa, s, array, index))
       return true;
  std::string sig;
  AstNodePtr f;
  if (fa.IsFunctionCall(s, &f,&args) && fa.IsVarRef(f,0,&sig) && sig == funcname) {
      AstInterface::AstNodeList::const_iterator p = args.begin();
      if (array != 0)
        *array = *p;
      if (index != 0) {
         for (++p; p != args.end(); ++p) {
            index->push_back(*p);
         }
      }
      return true;
  }
  return false;
}
예제 #6
0
SymbolicVal SymbolicValGenerator ::
GetSymbolicVal( AstInterface &fa, const AstNodePtr& exp)
{
  std::string name;
  AstNodePtr scope;
  int val = 0;
  AstNodePtr s1, s2;
  AstInterface::AstNodeList l;
  AstInterface::OperatorEnum opr = (AstInterface::OperatorEnum)0;
  if (fa.IsVarRef(exp, 0, &name, &scope)) {
     return new SymbolicVar( name, scope );
  }
  else if (fa.IsConstInt(exp, &val)) {
     return new SymbolicConst( val );
  }
  else if (fa.IsBinaryOp(exp, &opr, &s1, &s2)) {
     SymbolicVal v1 = GetSymbolicVal( fa, s1 ), v2 = GetSymbolicVal(fa, s2);
     switch (opr) {
     case AstInterface::BOP_TIMES: return v1 * v2;
     case AstInterface::BOP_PLUS: return v1 + v2;
     case AstInterface::BOP_MINUS: return v1 - v2;
     case AstInterface::BOP_DOT_ACCESS:
     case AstInterface::BOP_ARROW_ACCESS: 
     case AstInterface::BOP_DIVIDE:
        return new SymbolicFunction( opr, "/", v1,v2);
     case AstInterface::BOP_EQ: 
        return new SymbolicFunction( opr, "==", v1,v2);
     case AstInterface::BOP_LE: 
        return new SymbolicFunction( opr, "<=", v1,v2);
     case AstInterface::BOP_LT: 
        return new SymbolicFunction( opr, "<", v1,v2);
     case AstInterface::BOP_NE: 
        return new SymbolicFunction( opr, "!=", v1,v2);
     case AstInterface::BOP_GT: 
        return new SymbolicFunction( opr, ">", v1,v2);
     case AstInterface::BOP_GE: 
        return new SymbolicFunction( opr, ">=", v1,v2);
     case AstInterface::BOP_AND: 
        return new SymbolicFunction( opr, "&&", v1,v2);
     case AstInterface::BOP_OR:
        return new SymbolicFunction( opr, "||", v1,v2);
     default:
        assert(false);
     }
  }
  else if (fa.IsUnaryOp(exp, &opr, &s1)) {
    SymbolicVal v = GetSymbolicVal( fa, s1);
    switch (opr) {
    case AstInterface::UOP_MINUS: 
        return (-1) * v; 
    case AstInterface::UOP_ADDR:
        return new SymbolicFunction( opr, "&", v);
    case AstInterface::UOP_DEREF: 
        return new SymbolicFunction( opr, "*", v);
    case AstInterface::UOP_ALLOCATE:
        return new SymbolicFunction( opr, "new", v);
    case AstInterface::UOP_NOT:
        return new SymbolicFunction( opr, "!", v);
    case AstInterface::UOP_CAST:
        return new SymbolicFunction( opr, "cast", v);
    case AstInterface::UOP_DECR1:
        return new SymbolicFunction( opr, "--", v);
    case AstInterface::UOP_INCR1:
        return new SymbolicFunction( opr, "++", v);
    default:
       std::cerr << "Cannot handle " << AstToString(exp) << ":" << opr << "\n";
       assert(false);
     }
  }
  else if (fa.IsFunctionCall(exp, &s1, &l)) { 
     bool ismin = fa.IsMin(s1), ismax = fa.IsMax(s1);
     AstInterface::AstNodeList::const_iterator p = l.begin();
     if (ismin || ismax) {
       AstNodePtr s = *p;
       SymbolicVal v = GetSymbolicVal( fa, s );  
       for ( ++p; p != l.end(); ++p ) {
           s = *p;
           v = (ismin)? Min(v, GetSymbolicVal(fa, s)) 
                        : Max(v, GetSymbolicVal(fa, s));
       }
       return v;
     }
     if (fa.IsVarRef(exp, 0, &name)) {    
        SymbolicFunction::Arguments args;
        for ( ; p != l.end(); ++p) { 
           SymbolicVal cur = GetSymbolicVal(fa, *p);
           args.push_back( cur );
        }
        return new SymbolicFunction( AstInterface::OP_NONE, name, args);
     }
  } 
  return new SymbolicAstWrap(exp);
}
예제 #7
0
void PtrAnal::
ProcessExpression( AstInterface& fa, const std::string& _modname, const AstNodePtr& rhs)
{
  AstInterface::OperatorEnum op;
  std::string modname = _modname;
  AstNodePtr p,p1,p2;
  AstInterface::AstNodeList args, out;
  if (fa.IsFunctionCall(rhs, &p, &args, &out)) {
     typedef std::pair<AstNodePtr,std::string>  RefRec;
     std::list<RefRec>  refs;
     std::string fname = Get_VarName(fa,p);
     refs.push_back(RefRec(p,fname));
     std::list<std::string> pargs, pres;
     for (AstInterface::AstNodeList::const_iterator p = args.begin(); 
          p != args.end(); ++p) {
         AstNodePtr cur = *p;
         std::string curname = Get_VarName(fa, cur); 
         pargs.push_back(curname);
         refs.push_back(RefRec(cur,curname));
     }
     pres.push_back(modname);
     for (AstInterface::AstNodeList::const_iterator p2 = out.begin(); 
          p2 != out.end(); ++p2) {
         AstNodePtr cur = *p2;
         std::string curname = Get_VarName(fa, cur); 
         pres.push_back(curname);
         refs.push_back(RefRec(cur,curname));
     }
     Stmt stmt = funccall_x(fname, pargs, pres); 
     stmts_pushback(stmts,stmt);
     for (std::list<RefRec>::const_iterator p3 = refs.begin();
          p3 != refs.end(); ++p3) {
        RefRec cur = *p3;
        namemap[cur.first.get_ptr()] = PtrAnal::VarRef(stmt,cur.second);
     }
  }
  else if (fa.IsUnaryOp(rhs,&op, &p) ) {
        std::string readname;
        if (modname == "") {
           modname = Local_GetVarName(fa, rhs);
        }
        switch (op) {
        case AstInterface::UOP_ADDR: {
           readname= Get_VarName(fa, p); 
           Stmt stmt = x_eq_addr_y(modname, readname); 
           stmts_pushback(stmts,stmt);
           namemap[p.get_ptr()] = VarRef(stmt,readname);
           namemap[rhs.get_ptr()] = VarRef(stmt,modname);
           break;
        }
        case AstInterface::UOP_DEREF:  {
           readname= Get_VarName(fa, p); 
           Stmt stmt = x_eq_deref_y(modname, "", readname);
           stmts_pushback(stmts,stmt);
           namemap[p.get_ptr()] = VarRef(stmt,readname);
           namemap[rhs.get_ptr()] = VarRef(stmt,modname);
           break;
        }
        case AstInterface::UOP_ALLOCATE: {
           Stmt stmt = allocate_x(modname) ; 
           stmts_pushback(stmts,stmt);
           break;
         }
        default: {
           readname = Get_VarName(fa,p);
           std::list<std::string> opds;
           opds.push_back(readname);
           Stmt stmt_last = x_eq_op_y(OTHER,modname, opds);
           stmts_pushback(stmts,stmt_last);
           namemap[p.get_ptr()] = VarRef(stmt_last,readname);
           namemap[rhs.get_ptr()] = VarRef(stmt_last,modname);
           break;
         }
        }
   }
   else if (fa.IsBinaryOp(rhs, &op, &p1, &p2)) {
      std::list<std::string> opds;
      std::string readname , refname;
      if (modname == "") {
           modname = Local_GetVarName(fa, rhs);
      }
      Stmt stmt_last=0;
      switch (op) {
      case  AstInterface::BOP_DOT_ACCESS:  {
          readname = Get_VarName(fa, p1);
          refname = Local_GetFieldName(fa, p2);
          stmt_last = x_eq_field_y( modname, refname, readname);
          stmts_pushback(stmts,stmt_last);
             break;
       }
      case  AstInterface::BOP_ARROW_ACCESS:  {
          readname = Get_VarName(fa, p1);
          refname = Local_GetFieldName(fa, p2);
          stmt_last = x_eq_deref_y(modname, refname, readname);
          stmts_pushback(stmts,stmt_last);
             break;
       }
      default: {
         readname = Get_VarName(fa,p1);
         refname = Get_VarName(fa,p2);
         opds.push_back(readname);
         opds.push_back(refname);
         OpType opt = OTHER;
         switch (op) {
         case AstInterface::BOP_EQ: opt = EQ; break;
         case AstInterface::BOP_LT: opt = LT; break;
         case AstInterface::BOP_GT: opt = GT; break;
         case AstInterface::BOP_LE: opt = LE; break;
         case AstInterface::BOP_GE: opt = GE; break;
         case AstInterface::BOP_NE: opt = NE; break;
         default: break;
         }
         stmt_last = x_eq_op_y( opt, modname, opds);
         stmts_pushback(stmts,stmt_last);
      }
     }
      namemap[p1.get_ptr()] = VarRef(stmt_last,readname);
      namemap[p2.get_ptr()] = VarRef(stmt_last,refname);
      namemap[rhs.get_ptr()] = VarRef(stmt_last,modname);
   }
   else {
      std::string cur = Get_VarName(fa, rhs);
      assert  (cur != "");
      if (modname != "") { 
         Stmt stmt_last = x_eq_y(modname, cur); 
         stmts_pushback(stmts,stmt_last);
         namemap[rhs.get_ptr()] = VarRef(stmt_last,cur);
      }
   }
}