void addTemp(Parameter p, Expression actual, List<Expression> newParams, VarReplacer vr) {
   String name = varGen.nextVar(p.getName());
   addStatement(new StmtVarDecl(actual, (Type) p.getType().accept(vr), name, actual));
   Expression ev = new ExprVar(actual, name);
   newParams.add(ev);
   after.add(new StmtAssign(actual, ev));
 }
  public Object visitExprFunCall(ExprFunCall efc) {
    Function fun = nres.getFun(efc.getName());
    List<Expression> newParams = new ArrayList<Expression>(fun.getParams().size());
    Map<Expression, Integer> pset = new HashMap<Expression, Integer>();
    Iterator<Expression> eit = efc.getParams().iterator();
    for (Parameter p : fun.getParams()) {
      Expression actual = eit.next();

      {
        ExprVar ev = getBaseVar(actual);
        if (ev != null && pset.containsKey(ev)) {
          pset.put(ev, pset.get(ev) + 1);
        } else {
          pset.put(ev, 1);
        }
      }
    }
    boolean hasChanged = false;
    eit = efc.getParams().iterator();

    Map<String, Expression> repl = new HashMap<String, Expression>();
    VarReplacer vr = new VarReplacer(repl);

    for (Parameter p : fun.getParams()) {
      Expression actual = eit.next();
      repl.put(p.getName(), actual);
      if (p.isParameterOutput()) {
        ExprVar ev = getBaseVar(actual);
        if (ev == null) {
          newParams.add(actual);
          continue;
        }
        if (ev == FromHeap) {
          addTemp(p, actual, newParams, vr);
          hasChanged = true;
          continue;
        }
        int cnt = pset.get(ev);
        if (cnt > 1) {
          addTemp(p, actual, newParams, vr);
          hasChanged = true;
        } else {
          newParams.add(actual);
        }
      } else {
        newParams.add(actual);
      }
    }

    if (!hasChanged) addStatement(new StmtExpr(efc));
    else addStatement(new StmtExpr(new ExprFunCall(efc, efc.getName(), newParams)));
    addStatements(after);
    after.clear();
    return null;
  }
 @Override
 public Object visitExprFunCall(ExprFunCall exp) {
   exp = (ExprFunCall) super.visitExprFunCall(exp);
   Function callee = nres.getFun(exp.getName());
   Map<String, Expression> repl = new HashMap<String, Expression>();
   VarReplacer vr = new VarReplacer(repl);
   for (ZipIdxEnt<Expression> arg : zipwithindex(exp.getParams())) {
     Expression actual = arg.entry;
     Parameter p = callee.getParams().get(arg.idx);
     Type t = p.getType();
     repl.put(p.getName(), actual);
     upgradeStarToInt(actual, (Type) t.accept(vr));
   }
   return exp;
 }
 @Override
 public Object visitFunction(Function fcn) {
   if (fcn.isSketchHarness()
       || fcn.getSpecification() != null
       || specFcns.contains(fcn.getName())
       || !fcn.isStatic()) {
     return fcn;
   } else {
     this.parametersToInout = new TypedHashSet<String>();
     this.inputParameters = new Vector<String>();
     for (Parameter param : fcn.getParams()) {
       if (!param.isParameterOutput()) {
         this.inputParameters.add(param.getName());
       }
     }
     super.visitFunction(fcn);
     if (parametersToInout.isEmpty()) {
       return fcn;
     } else {
       Vector<Parameter> newParams = new Vector<Parameter>();
       for (Parameter param : fcn.getParams()) {
         if (parametersToInout.contains(param.getName())) {
           newParams.add(new Parameter(param, param.getType(), param.getName(), Parameter.REF));
         } else {
           newParams.add(param);
         }
       }
       return fcn.creator().params(newParams).create();
     }
   }
 }
Beispiel #5
0
  private Function addAssumes(Function f) {
    Map<Expression, Expression> lenVars = new HashMap<Expression, Expression>();
    List<Statement> stmts = new ArrayList<Statement>();
    for (Parameter p : f.getParams()) {
      Type t = p.getType();
      if (t.isArray()) {
        TypeArray ta = (TypeArray) t;
        Type tb = ta.getBase();
        if (!tb.isArray()) {
          Expression len = ta.getLength();
          if (!len.isConstant()) {
            Expression v = lenVars.get(len);
            if (v == null) {
              String vname = varGen.nextVar("valen_" + p.getName());
              v = new ExprVar(p, vname);
              lenVars.put(len, v);
              stmts.add(new StmtVarDecl(p, TypePrimitive.inttype, vname, len));
            }
            Expression zero = tb.defaultValue();
            Expression arr = new ExprVar(p, p.getName());
            for (int j = 0; j < arrSize; ++j) {
              Expression jexp = constInts.get(j);
              Expression cond1 = new ExprBinary(p, ExprBinary.BINOP_GT, v, jexp);
              Expression cond2 =
                  new ExprBinary(p, ExprBinary.BINOP_EQ, zero, new ExprArrayRange(arr, jexp));
              stmts.add(
                  new StmtAssume(
                      p,
                      new ExprBinary(p, ExprBinary.BINOP_OR, cond1, cond2),
                      "trunc " + p.getName() + " " + j));
            }
          }
        }
      }
    }

    if (stmts.isEmpty()) {
      return f;
    } else {
      stmts.addAll(((StmtBlock) f.getBody()).getStmts());
      return f.creator().body(new StmtBlock(stmts)).create();
    }
  }