Program: 132767
Project: 132767
Buggy source:
/** 
 * Try to piggyback decrement operations on instructions in block TODO: this doesn't factor in alias info: if we're storing to an alias (e.g. struct field), we could piggyback a decrement for the root of he struct E.g. see test 367
 * @param logger
 * @param fn
 * @param block
 * @param tracker
 * @param rcType
 */
private void piggybackDecrementsOnInstructions(Logger logger,Function fn,Block block,RCTracker tracker,RefCountType rcType){
  if (!RCUtil.piggybackEnabled()) {
    return;
  }
  RefCountCandidates candidates=tracker.getVarCandidates(block,rcType,RCDir.DECR);
  UseFinder subblockWalker=new UseFinder(tracker,rcType,candidates.varKeySet(),null);
  ListIterator<Continuation> cit=block.continuationEndIterator();
  while (cit.hasPrevious()) {
    Continuation cont=cit.previous();
    if (RCUtil.isAsyncForeachLoop(cont)) {
      AbstractForeachLoop loop=(AbstractForeachLoop)cont;
      Var piggybacked;
      do {
        piggybacked=loop.tryPiggyBack(candidates,rcType,RCDir.DECR);
        if (piggybacked != null) {
          if (logger.isTraceEnabled()) {
            logger.trace("String_Node_Str" + piggybacked + "String_Node_Str"+ rcType+ "String_Node_Str"+ candidates.getCount(piggybacked));
          }
          candidates.reset(piggybacked);
          tracker.reset(rcType,piggybacked,RCDir.DECR);
        }
      }
 while (piggybacked != null);
    }
    subblockWalker.reset();
    TreeWalk.walkSyncChildren(logger,fn,cont,subblockWalker);
    removeCandidates(subblockWalker.getUsedVars(),tracker,candidates);
  }
  List<VarCount> successful=new ArrayList<VarCount>();
  ListIterator<Statement> it=block.statementEndIterator();
  while (it.hasPrevious()) {
    Statement stmt=it.previous();
switch (stmt.type()) {
case INSTRUCTION:
{
        Instruction inst=stmt.instruction();
        if (logger.isTraceEnabled()) {
          logger.trace("String_Node_Str" + inst);
        }
        VarCount piggybacked;
        do {
          piggybacked=inst.tryPiggyback(candidates,rcType);
          if (piggybacked != null && piggybacked.count != 0) {
            if (logger.isTraceEnabled()) {
              logger.trace("String_Node_Str" + piggybacked + "String_Node_Str"+ inst);
            }
            candidates.add(piggybacked.var,-piggybacked.count);
            successful.add(piggybacked);
          }
        }
 while (piggybacked != null && piggybacked.count != 0);
        List<Var> used=findUses(inst,tracker,rcType,candidates.varKeySet());
        removeCandidates(used,tracker,candidates);
        break;
      }
case CONDITIONAL:
    subblockWalker.reset();
  TreeWalk.walkSyncChildren(logger,fn,stmt.conditional(),subblockWalker);
removeCandidates(subblockWalker.getUsedVars(),tracker,candidates);
break;
default :
throw new STCRuntimeError("String_Node_Str" + stmt.type());
}
}
if (logger.isTraceEnabled()) {
logger.trace(successful);
}
for (VarCount vc : successful) {
assert(vc != null);
tracker.cancel(tracker.getRefCountVar(vc.var),rcType,-vc.count);
}
}

Fixed version (ground truth):
/** 
 * Try to piggyback decrement operations on instructions in block
 * @param logger
 * @param fn
 * @param block
 * @param tracker
 * @param rcType
 */
private void piggybackDecrementsOnInstructions(Logger logger,Function fn,Block block,RCTracker tracker,RefCountType rcType){
  if (!RCUtil.piggybackEnabled()) {
    return;
  }
  RefCountCandidates candidates=tracker.getVarCandidates(block,rcType,RCDir.DECR);
  UseFinder subblockWalker=new UseFinder(tracker,rcType,candidates.varKeySet(),null);
  ListIterator<Continuation> cit=block.continuationEndIterator();
  while (cit.hasPrevious()) {
    Continuation cont=cit.previous();
    if (RCUtil.isAsyncForeachLoop(cont)) {
      AbstractForeachLoop loop=(AbstractForeachLoop)cont;
      VarCount piggybacked;
      do {
        piggybacked=loop.tryPiggyBack(candidates,rcType,RCDir.DECR);
        if (piggybacked != null) {
          if (logger.isTraceEnabled()) {
            logger.trace("String_Node_Str" + piggybacked + "String_Node_Str"+ rcType+ "String_Node_Str"+ piggybacked.count);
          }
          candidates.add(piggybacked.var,-piggybacked.count);
          tracker.cancel(tracker.getRefCountVar(piggybacked.var),rcType,-piggybacked.count);
        }
      }
 while (piggybacked != null);
    }
    subblockWalker.reset();
    TreeWalk.walkSyncChildren(logger,fn,cont,subblockWalker);
    removeCandidates(subblockWalker.getUsedVars(),tracker,candidates);
  }
  List<VarCount> successful=new ArrayList<VarCount>();
  ListIterator<Statement> it=block.statementEndIterator();
  while (it.hasPrevious()) {
    Statement stmt=it.previous();
switch (stmt.type()) {
case INSTRUCTION:
{
        Instruction inst=stmt.instruction();
        if (logger.isTraceEnabled()) {
          logger.trace("String_Node_Str" + inst);
        }
        VarCount piggybacked;
        do {
          piggybacked=inst.tryPiggyback(candidates,rcType);
          if (piggybacked != null && piggybacked.count != 0) {
            if (logger.isTraceEnabled()) {
              logger.trace("String_Node_Str" + piggybacked + "String_Node_Str"+ inst);
            }
            candidates.add(piggybacked.var,-piggybacked.count);
            successful.add(piggybacked);
          }
        }
 while (piggybacked != null && piggybacked.count != 0);
        List<Var> used=findUses(inst,tracker,rcType,candidates.varKeySet());
        removeCandidates(used,tracker,candidates);
        break;
      }
case CONDITIONAL:
    subblockWalker.reset();
  TreeWalk.walkSyncChildren(logger,fn,stmt.conditional(),subblockWalker);
removeCandidates(subblockWalker.getUsedVars(),tracker,candidates);
break;
default :
throw new STCRuntimeError("String_Node_Str" + stmt.type());
}
}
if (logger.isTraceEnabled()) {
logger.trace(successful);
}
for (VarCount vc : successful) {
assert(vc != null);
tracker.cancel(tracker.getRefCountVar(vc.var),rcType,-vc.count);
}
}