Program: 132643
Project: 132643
Buggy source:
/** 
 * Fetch the value of a variable
 * @param block
 * @param instBuffer append fetch instruction to this list
 * @param var the variable to fetch the value of
 * @param acquireWrite if the var is a reference, do we acquirewrite refcounts?
 * @return variable holding value
 */
public static Var fetchValueOf(Block block,List<? super Instruction> instBuffer,Var var,String valName,boolean recursive,boolean acquireWrite){
  Type valueT;
  if (recursive && Types.isContainer(var)) {
    valueT=Types.unpackedType(var);
  }
 else {
    valueT=Types.retrievedType(var);
  }
  if (Types.isPrimUpdateable(var)) {
    Var value_v=createValueVar(valName,valueT,var);
    block.addVariable(value_v);
    instBuffer.add(TurbineOp.latestValue(value_v,var));
    return value_v;
  }
 else   if (Types.isPrimFuture(var)) {
    Var value_v=createValueVar(valName,valueT,var);
    block.addVariable(value_v);
    instBuffer.add(ICInstructions.retrievePrim(value_v,var));
    if (Types.isBlobVal(valueT)) {
      block.addCleanup(value_v,TurbineOp.freeBlob(value_v));
    }
    return value_v;
  }
 else   if (Types.isRef(var)) {
    Var deref=new Var(valueT,valName,Alloc.ALIAS,DefType.LOCAL_COMPILER,VarProvenance.valueOf(var));
    block.addVariable(deref);
    instBuffer.add(TurbineOp.retrieveRef(deref,var,acquireWrite));
    return deref;
  }
 else   if (Types.isContainer(var) && recursive) {
    Var deref=new Var(valueT,valName,Alloc.LOCAL,DefType.LOCAL_COMPILER,VarProvenance.valueOf(var));
    block.addVariable(deref);
    instBuffer.add(TurbineOp.retrieveRecursive(deref,var));
    return deref;
  }
 else   if (Types.isStruct(var) && recursive) {
    Var deref=new Var(valueT,valName,Alloc.LOCAL,DefType.LOCAL_COMPILER,VarProvenance.valueOf(var));
    block.addVariable(deref);
    Instruction structRetrieve=TurbineOp.retrieveStruct(deref,var);
    for (    StructField f : ((StructType)var.type().getImplType()).getFields()) {
      if (Types.isRef(f.getType())) {
        structRetrieve=TurbineOp.retrieveRecursive(deref,var);
      }
    }
    instBuffer.add(structRetrieve);
    return deref;
  }
 else   if ((Types.isContainer(var) || Types.isStruct(var)) && !recursive) {
    Var deref=new Var(valueT,valName,Alloc.LOCAL,DefType.LOCAL_COMPILER,VarProvenance.valueOf(var));
    block.addVariable(deref);
    if (Types.isArray(var)) {
      instBuffer.add(TurbineOp.retrieveArray(deref,var));
    }
 else     if (Types.isBag(var)) {
      instBuffer.add(TurbineOp.retrieveBag(deref,var));
    }
 else {
      assert(Types.isStruct(var));
      instBuffer.add(TurbineOp.retrieveStruct(deref,var));
    }
    return deref;
  }
 else {
    throw new STCRuntimeError("String_Node_Str");
  }
}

Fixed version (ground truth):
/** 
 * Fetch the value of a variable
 * @param block
 * @param instBuffer append fetch instruction to this list
 * @param var the variable to fetch the value of
 * @param acquireWrite if the var is a reference, do we acquirewrite refcounts?
 * @return variable holding value
 */
public static Var fetchValueOf(Block block,List<? super Instruction> instBuffer,Var var,String valName,boolean recursive,boolean acquireWrite){
  Type valueT=Types.retrievedType(var,recursive);
  if (Types.isPrimUpdateable(var)) {
    Var value_v=createValueVar(valName,valueT,var);
    block.addVariable(value_v);
    instBuffer.add(TurbineOp.latestValue(value_v,var));
    return value_v;
  }
 else   if (Types.isPrimFuture(var)) {
    Var value_v=createValueVar(valName,valueT,var);
    block.addVariable(value_v);
    instBuffer.add(ICInstructions.retrievePrim(value_v,var));
    if (Types.isBlobVal(valueT)) {
      block.addCleanup(value_v,TurbineOp.freeBlob(value_v));
    }
    return value_v;
  }
 else   if (Types.isRef(var)) {
    Var deref=new Var(valueT,valName,Alloc.ALIAS,DefType.LOCAL_COMPILER,VarProvenance.valueOf(var));
    block.addVariable(deref);
    instBuffer.add(TurbineOp.retrieveRef(deref,var,acquireWrite));
    return deref;
  }
 else   if (Types.isContainer(var) && recursive) {
    Var deref=new Var(valueT,valName,Alloc.LOCAL,DefType.LOCAL_COMPILER,VarProvenance.valueOf(var));
    block.addVariable(deref);
    instBuffer.add(TurbineOp.retrieveRecursive(deref,var));
    return deref;
  }
 else   if (Types.isStruct(var) && recursive) {
    Var deref=new Var(valueT,valName,Alloc.LOCAL,DefType.LOCAL_COMPILER,VarProvenance.valueOf(var));
    block.addVariable(deref);
    boolean mustUseRecursive=false;
    for (    StructField f : ((StructType)var.type().getImplType()).getFields()) {
      if (Types.isRef(f.getType())) {
        mustUseRecursive=true;
      }
    }
    Instruction structRetrieve=mustUseRecursive ? TurbineOp.retrieveRecursive(deref,var) : TurbineOp.retrieveStruct(deref,var);
    instBuffer.add(structRetrieve);
    return deref;
  }
 else   if ((Types.isContainer(var) || Types.isStruct(var)) && !recursive) {
    Var deref=new Var(valueT,valName,Alloc.LOCAL,DefType.LOCAL_COMPILER,VarProvenance.valueOf(var));
    block.addVariable(deref);
    if (Types.isArray(var)) {
      instBuffer.add(TurbineOp.retrieveArray(deref,var));
    }
 else     if (Types.isBag(var)) {
      instBuffer.add(TurbineOp.retrieveBag(deref,var));
    }
 else {
      assert(Types.isStruct(var));
      instBuffer.add(TurbineOp.retrieveStruct(deref,var));
    }
    return deref;
  }
 else {
    throw new STCRuntimeError("String_Node_Str");
  }
}