Program: 133230
Project: 133230
Buggy source:
/** 
 * Handle the general foreach loop where we are looping over array
 * @param context
 * @param loop
 * @throws UserException
 * @throws UndefinedTypeException
 */
private void foreachArray(Context context,ForeachLoop loop) throws UserException, UndefinedTypeException {
  Var arrayVar=exprWalker.eval(context,loop.getArrayVarTree(),loop.findArrayType(context),true,null);
  ArrayList<Var> usedVariables=new ArrayList<Var>();
  ArrayList<Var> keepOpenVars=new ArrayList<Var>();
  VariableUsageInfo bodyVU=loop.getBody().checkedGetVariableUsage();
  summariseBranchVariableUsage(context,Arrays.asList(bodyVU),usedVariables,keepOpenVars);
  for (  Var v : keepOpenVars) {
    if (v.name().equals(arrayVar.name())) {
      throw new STCRuntimeError("String_Node_Str" + v.name() + "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str");
    }
  }
  FunctionContext fc=context.getFunctionContext();
  Var realArray;
  Context outsideLoopContext;
  ArrayList<Var> arrRefWaitUsedVars=null;
  if (Types.isArrayRef(arrayVar.type())) {
    arrRefWaitUsedVars=new ArrayList<Var>(usedVariables);
    arrRefWaitUsedVars.add(arrayVar);
    backend.startWaitStatement(fc.constructName("String_Node_Str"),Arrays.asList(arrayVar),arrRefWaitUsedVars,keepOpenVars,WaitMode.DATA_ONLY,TaskMode.LOCAL);
    outsideLoopContext=new LocalContext(context);
    realArray=varCreator.createTmp(outsideLoopContext,arrayVar.type().memberType(),false,true);
    backend.retrieveRef(realArray,arrayVar);
  }
 else {
    realArray=arrayVar;
    outsideLoopContext=context;
  }
  ArrayList<Var> waitUsedVars=new ArrayList<Var>(usedVariables);
  waitUsedVars.add(realArray);
  backend.startWaitStatement(fc.constructName("String_Node_Str"),Arrays.asList(realArray),waitUsedVars,keepOpenVars,WaitMode.DATA_ONLY,TaskMode.LOCAL);
  loop.setupLoopBodyContext(outsideLoopContext);
  Context loopBodyContext=loop.getBodyContext();
  backend.startForeachLoop(realArray,loop.getMemberVar(),loop.getLoopCountVal(),loop.getSplitDegree(),true,usedVariables,keepOpenVars);
  ArrayList<Var> iterUsedVars=null;
  if (!loop.isSyncLoop()) {
    iterUsedVars=new ArrayList<Var>(usedVariables);
    if (loop.getLoopCountVal() != null)     iterUsedVars.add(loop.getLoopCountVal());
    backend.startWaitStatement(fc.constructName("String_Node_Str"),Collections.<Var>emptyList(),iterUsedVars,keepOpenVars,WaitMode.TASK_DISPATCH,TaskMode.CONTROL);
  }
  if (loop.getCountVarName() != null) {
    Var loopCountVar=varCreator.createVariable(loop.getBodyContext(),Types.F_INT,loop.getCountVarName(),VarStorage.STACK,DefType.LOCAL_USER,null);
    backend.assignInt(loopCountVar,Arg.createVar(loop.getLoopCountVal()));
  }
  block(loopBodyContext,loop.getBody());
  if (!loop.isSyncLoop()) {
    backend.endWaitStatement(iterUsedVars,keepOpenVars);
  }
  backend.endForeachLoop(loop.getSplitDegree(),true,usedVariables,keepOpenVars);
  backend.endWaitStatement(waitUsedVars,keepOpenVars);
  if (Types.isArrayRef(arrayVar.type())) {
    backend.endWaitStatement(arrRefWaitUsedVars,keepOpenVars);
  }
}

Fixed version (ground truth):
/** 
 * Handle the general foreach loop where we are looping over array
 * @param context
 * @param loop
 * @throws UserException
 * @throws UndefinedTypeException
 */
private void foreachArray(Context context,ForeachLoop loop) throws UserException, UndefinedTypeException {
  Var arrayVar=exprWalker.eval(context,loop.getArrayVarTree(),loop.findArrayType(context),true,null);
  ArrayList<Var> usedVariables=new ArrayList<Var>();
  ArrayList<Var> keepOpenVars=new ArrayList<Var>();
  VariableUsageInfo bodyVU=loop.getBody().checkedGetVariableUsage();
  summariseBranchVariableUsage(context,Arrays.asList(bodyVU),usedVariables,keepOpenVars);
  for (  Var v : keepOpenVars) {
    if (v.name().equals(arrayVar.name())) {
      throw new STCRuntimeError("String_Node_Str" + v.name() + "String_Node_Str"+ "String_Node_Str"+ "String_Node_Str");
    }
  }
  FunctionContext fc=context.getFunctionContext();
  int loopNum=fc.getCounterVal("String_Node_Str");
  Var realArray;
  Context outsideLoopContext;
  ArrayList<Var> arrRefWaitUsedVars=null;
  if (Types.isArrayRef(arrayVar.type())) {
    arrRefWaitUsedVars=new ArrayList<Var>(usedVariables);
    arrRefWaitUsedVars.add(arrayVar);
    backend.startWaitStatement(fc.getFunctionName() + "String_Node_Str" + loopNum,Arrays.asList(arrayVar),arrRefWaitUsedVars,keepOpenVars,WaitMode.DATA_ONLY,TaskMode.LOCAL);
    outsideLoopContext=new LocalContext(context);
    realArray=varCreator.createTmp(outsideLoopContext,arrayVar.type().memberType(),false,true);
    backend.retrieveRef(realArray,arrayVar);
  }
 else {
    realArray=arrayVar;
    outsideLoopContext=context;
  }
  ArrayList<Var> waitUsedVars=new ArrayList<Var>(usedVariables);
  waitUsedVars.add(realArray);
  backend.startWaitStatement(fc.getFunctionName() + "String_Node_Str" + loopNum,Arrays.asList(realArray),waitUsedVars,keepOpenVars,WaitMode.DATA_ONLY,TaskMode.LOCAL);
  loop.setupLoopBodyContext(outsideLoopContext);
  Context loopBodyContext=loop.getBodyContext();
  backend.startForeachLoop(fc.getFunctionName() + "String_Node_Str" + loopNum,realArray,loop.getMemberVar(),loop.getLoopCountVal(),loop.getSplitDegree(),true,usedVariables,keepOpenVars);
  ArrayList<Var> iterUsedVars=null;
  if (!loop.isSyncLoop()) {
    iterUsedVars=new ArrayList<Var>(usedVariables);
    if (loop.getLoopCountVal() != null)     iterUsedVars.add(loop.getLoopCountVal());
    backend.startWaitStatement(fc.getFunctionName() + "String_Node_Str" + loopNum,Collections.<Var>emptyList(),iterUsedVars,keepOpenVars,WaitMode.TASK_DISPATCH,TaskMode.CONTROL);
  }
  if (loop.getCountVarName() != null) {
    Var loopCountVar=varCreator.createVariable(loop.getBodyContext(),Types.F_INT,loop.getCountVarName(),VarStorage.STACK,DefType.LOCAL_USER,null);
    backend.assignInt(loopCountVar,Arg.createVar(loop.getLoopCountVal()));
  }
  block(loopBodyContext,loop.getBody());
  if (!loop.isSyncLoop()) {
    backend.endWaitStatement(iterUsedVars,keepOpenVars);
  }
  backend.endForeachLoop(loop.getSplitDegree(),true,usedVariables,keepOpenVars);
  backend.endWaitStatement(waitUsedVars,keepOpenVars);
  if (Types.isArrayRef(arrayVar.type())) {
    backend.endWaitStatement(arrRefWaitUsedVars,keepOpenVars);
  }
}