Program: 88722
Project: 88722
Buggy source:
/** 
 * Eliminates dead code in a linear fashion.  Complexity is linear  with respect to the statements. Does not work on grimp code because of the check on the right hand side for side effects. 
 */
protected void internalTransform(Body b,String phaseName,Map options){
  boolean eliminateOnlyStackLocals=PhaseOptions.getBoolean(options,"String_Node_Str");
  if (Options.v().verbose())   G.v().out.println("String_Node_Str" + b.getMethod().getName() + "String_Node_Str");
  if (Options.v().time())   Timers.v().deadCodeTimer.start();
  Set essentialStmts=new HashSet();
  LinkedList toVisit=new LinkedList();
  Chain units=b.getUnits();
{
    Iterator stmtIt=units.iterator();
    while (stmtIt.hasNext()) {
      Stmt s=(Stmt)stmtIt.next();
      boolean isEssential=true;
      if (s instanceof NopStmt)       isEssential=false;
      if (s instanceof AssignStmt) {
        AssignStmt as=(AssignStmt)s;
        if (as.getLeftOp() instanceof Local && (!eliminateOnlyStackLocals || ((Local)as.getLeftOp()).getName().startsWith("String_Node_Str"))) {
          Value rhs=as.getRightOp();
          isEssential=false;
          if (rhs instanceof InvokeExpr || rhs instanceof ArrayRef) {
            isEssential=true;
          }
          if (rhs instanceof InstanceFieldRef && !(!b.getMethod().isStatic() && ((InstanceFieldRef)rhs).getBase() == b.getThisLocal())) {
            isEssential=true;
          }
 else           if (rhs instanceof DivExpr || rhs instanceof RemExpr) {
            BinopExpr expr=(BinopExpr)rhs;
            if (expr.getOp1().getType().equals(IntType.v()) || expr.getOp2().getType().equals(IntType.v()) || expr.getOp1().getType().equals(LongType.v())|| expr.getOp2().getType().equals(LongType.v())) {
              isEssential=true;
            }
          }
        }
      }
      if (isEssential) {
        essentialStmts.add(s);
        toVisit.addLast(s);
      }
    }
  }
  ExceptionalUnitGraph graph=new ExceptionalUnitGraph(b);
  LocalDefs defs=new SimpleLocalDefs(graph);
  LocalUses uses=new SimpleLocalUses(graph,defs);
{
    while (!toVisit.isEmpty()) {
      Stmt s=(Stmt)toVisit.removeFirst();
      Iterator boxIt=s.getUseBoxes().iterator();
      while (boxIt.hasNext()) {
        ValueBox box=(ValueBox)boxIt.next();
        if (box.getValue() instanceof Local) {
          Iterator defIt=defs.getDefsOfAt((Local)box.getValue(),s).iterator();
          while (defIt.hasNext()) {
            Stmt def=(Stmt)defIt.next();
            if (!essentialStmts.contains(def)) {
              essentialStmts.add(def);
              toVisit.addLast(def);
            }
          }
        }
      }
    }
  }
{
    Iterator stmtIt=units.iterator();
    while (stmtIt.hasNext()) {
      Stmt s=(Stmt)stmtIt.next();
      if (!essentialStmts.contains(s)) {
        stmtIt.remove();
        s.clearUnitBoxes();
      }
 else       if (s instanceof AssignStmt && ((AssignStmt)s).getLeftOp() == ((AssignStmt)s).getRightOp() && ((AssignStmt)s).getLeftOp() instanceof Local) {
        stmtIt.remove();
        s.clearUnitBoxes();
      }
    }
  }
{
    Iterator stmtIt=units.snapshotIterator();
    while (stmtIt.hasNext()) {
      Stmt s=(Stmt)stmtIt.next();
      if (s instanceof AssignStmt && s.containsInvokeExpr()) {
        Local l=(Local)((AssignStmt)s).getLeftOp();
        InvokeExpr e=(InvokeExpr)s.getInvokeExpr();
{
          Iterator useIt=uses.getUsesOf(s).iterator();
          boolean isEssential=false;
          while (useIt.hasNext()) {
            UnitValueBoxPair pair=(UnitValueBoxPair)useIt.next();
            if (essentialStmts.contains(pair.unit)) {
              isEssential=true;
              break;
            }
          }
          if (!isEssential) {
            Stmt newInvoke=Jimple.v().newInvokeStmt(e);
            units.swapWith(s,newInvoke);
          }
        }
      }
    }
  }
  if (Options.v().time())   Timers.v().deadCodeTimer.end();
}

Fixed version (ground truth):
/** 
 * Eliminates dead code in a linear fashion.  Complexity is linear  with respect to the statements. Does not work on grimp code because of the check on the right hand side for side effects. 
 */
protected void internalTransform(Body b,String phaseName,Map options){
  boolean eliminateOnlyStackLocals=PhaseOptions.getBoolean(options,"String_Node_Str");
  if (Options.v().verbose())   G.v().out.println("String_Node_Str" + b.getMethod().getName() + "String_Node_Str");
  if (Options.v().time())   Timers.v().deadCodeTimer.start();
  Set essentialStmts=new HashSet();
  LinkedList toVisit=new LinkedList();
  Chain units=b.getUnits();
{
    Iterator stmtIt=units.iterator();
    while (stmtIt.hasNext()) {
      Stmt s=(Stmt)stmtIt.next();
      boolean isEssential=true;
      if (s instanceof NopStmt)       isEssential=false;
      if (s instanceof AssignStmt) {
        AssignStmt as=(AssignStmt)s;
        if (as.getLeftOp() instanceof Local && (!eliminateOnlyStackLocals || ((Local)as.getLeftOp()).getName().startsWith("String_Node_Str"))) {
          Value rhs=as.getRightOp();
          isEssential=false;
          if (rhs instanceof InvokeExpr || rhs instanceof ArrayRef) {
            isEssential=true;
          }
          if (rhs instanceof InstanceFieldRef && !(!b.getMethod().isStatic() && ((InstanceFieldRef)rhs).getBase() == b.getThisLocal())) {
            isEssential=true;
          }
 else           if (rhs instanceof DivExpr || rhs instanceof RemExpr) {
            BinopExpr expr=(BinopExpr)rhs;
            if (expr.getOp1().getType().equals(IntType.v()) || expr.getOp2().getType().equals(IntType.v()) || expr.getOp1().getType().equals(LongType.v())|| expr.getOp2().getType().equals(LongType.v())) {
              isEssential=true;
            }
          }
        }
      }
      if (isEssential) {
        essentialStmts.add(s);
        toVisit.addLast(s);
      }
    }
  }
  ExceptionalUnitGraph graph=new ExceptionalUnitGraph(b);
  LocalDefs defs=new SimpleLocalDefs(graph);
  LocalUses uses=new SimpleLocalUses(graph,defs);
{
    while (!toVisit.isEmpty()) {
      Stmt s=(Stmt)toVisit.removeFirst();
      Iterator boxIt=s.getUseBoxes().iterator();
      while (boxIt.hasNext()) {
        ValueBox box=(ValueBox)boxIt.next();
        if (box.getValue() instanceof Local) {
          Iterator defIt=defs.getDefsOfAt((Local)box.getValue(),s).iterator();
          while (defIt.hasNext()) {
            Stmt def=(Stmt)defIt.next();
            if (!essentialStmts.contains(def)) {
              essentialStmts.add(def);
              toVisit.addLast(def);
            }
          }
        }
      }
    }
  }
{
    Iterator stmtIt=units.iterator();
    while (stmtIt.hasNext()) {
      Stmt s=(Stmt)stmtIt.next();
      if (!essentialStmts.contains(s)) {
        stmtIt.remove();
        s.clearUnitBoxes();
      }
 else       if (s instanceof AssignStmt && ((AssignStmt)s).getLeftOp() == ((AssignStmt)s).getRightOp() && ((AssignStmt)s).getLeftOp() instanceof Local) {
        stmtIt.remove();
        s.clearUnitBoxes();
      }
    }
  }
{
    Iterator stmtIt=units.snapshotIterator();
    while (stmtIt.hasNext()) {
      Stmt s=(Stmt)stmtIt.next();
      if (s instanceof AssignStmt && s.containsInvokeExpr()) {
        Local l=(Local)((AssignStmt)s).getLeftOp();
        InvokeExpr e=(InvokeExpr)s.getInvokeExpr();
{
          Iterator useIt=uses.getUsesOf(s).iterator();
          boolean isEssential=false;
          while (useIt.hasNext()) {
            UnitValueBoxPair pair=(UnitValueBoxPair)useIt.next();
            if (essentialStmts.contains(pair.unit)) {
              isEssential=true;
              break;
            }
          }
          if (!isEssential) {
            Stmt newInvoke=Jimple.v().newInvokeStmt(e);
            newInvoke.addAllTagsOf(s);
            units.swapWith(s,newInvoke);
          }
        }
      }
    }
  }
  if (Options.v().time())   Timers.v().deadCodeTimer.end();
}