Program: 85282
Project: 85282
Buggy source:
protected Type findArrayType(LocalDefs localDefs,Stmt arrayStmt,int depth,Set<Unit> alreadyVisitedDefs){
  ArrayRef aRef=null;
  if (arrayStmt.containsArrayRef()) {
    aRef=arrayStmt.getArrayRef();
  }
  Local aBase=null;
  if (null == aRef) {
    if (arrayStmt instanceof AssignStmt) {
      AssignStmt stmt=(AssignStmt)arrayStmt;
      aBase=(Local)stmt.getRightOp();
    }
 else {
      throw new RuntimeException("String_Node_Str" + arrayStmt);
    }
  }
 else {
    aBase=(Local)aRef.getBase();
  }
  List<Unit> defsOfaBaseList=localDefs.getDefsOfAt(aBase,arrayStmt);
  if (defsOfaBaseList == null || defsOfaBaseList.isEmpty()) {
    throw new RuntimeException("String_Node_Str" + arrayStmt);
  }
  Type aType=null;
  int nullDefCount=0;
  for (  Unit baseDef : defsOfaBaseList) {
    Debug.printDbg("String_Node_Str",baseDef);
    if (alreadyVisitedDefs.contains(baseDef))     continue;
    Set<Unit> newVisitedDefs=new HashSet<Unit>(alreadyVisitedDefs);
    newVisitedDefs.add(baseDef);
    if (baseDef instanceof AssignStmt) {
      AssignStmt stmt=(AssignStmt)baseDef;
      Value r=stmt.getRightOp();
      if (r instanceof FieldRef) {
        Type t=((FieldRef)r).getFieldRef().type();
        if (t instanceof ArrayType) {
          ArrayType at=(ArrayType)t;
          t=at.getArrayElementType();
        }
        Debug.printDbg("String_Node_Str",t);
        if (depth == 0) {
          aType=t;
          break;
        }
 else {
          return t;
        }
      }
 else       if (r instanceof ArrayRef) {
        ArrayRef ar=(ArrayRef)r;
        if (ar.getType().equals("String_Node_Str") || ar.getType().toString().equals("String_Node_Str")) {
          System.out.println("String_Node_Str" + stmt);
          Type t=findArrayType(localDefs,stmt,++depth,newVisitedDefs);
          if (t instanceof ArrayType) {
            ArrayType at=(ArrayType)t;
            t=at.getArrayElementType();
          }
          if (depth == 0) {
            aType=t;
            break;
          }
 else {
            return t;
          }
        }
 else {
          Debug.printDbg("String_Node_Str",ar.getType().toString());
          ArrayType at=(ArrayType)stmt.getRightOp().getType();
          Type t=at.getArrayElementType();
          if (depth == 0) {
            aType=t;
            break;
          }
 else {
            return t;
          }
        }
      }
 else       if (r instanceof NewArrayExpr) {
        NewArrayExpr expr=(NewArrayExpr)r;
        Type t=expr.getBaseType();
        Debug.printDbg("String_Node_Str",t);
        if (depth == 0) {
          aType=t;
          break;
        }
 else {
          return t;
        }
      }
 else       if (r instanceof CastExpr) {
        Type t=(((CastExpr)r).getCastType());
        Debug.printDbg("String_Node_Str",t);
        if (t instanceof ArrayType) {
          ArrayType at=(ArrayType)t;
          t=at.getArrayElementType();
        }
        if (depth == 0) {
          aType=t;
          break;
        }
 else {
          return t;
        }
      }
 else       if (r instanceof InvokeExpr) {
        Type t=((InvokeExpr)r).getMethodRef().returnType();
        Debug.printDbg("String_Node_Str",t);
        if (t instanceof ArrayType) {
          ArrayType at=(ArrayType)t;
          t=at.getArrayElementType();
        }
        if (depth == 0) {
          aType=t;
          break;
        }
 else {
          return t;
        }
      }
 else       if (r instanceof Local) {
        Debug.printDbg("String_Node_Str",stmt);
        Type t=findArrayType(localDefs,stmt,++depth,newVisitedDefs);
        if (depth == 0) {
          aType=t;
        }
 else {
          aType=t;
        }
      }
 else       if (r instanceof Constant) {
        nullDefCount++;
      }
 else {
        throw new RuntimeException("String_Node_Str" + stmt);
      }
    }
 else     if (baseDef instanceof IdentityStmt) {
      IdentityStmt stmt=(IdentityStmt)baseDef;
      ArrayType at=(ArrayType)stmt.getRightOp().getType();
      Type t=at.getArrayElementType();
      if (depth == 0) {
        aType=t;
        break;
      }
 else {
        return t;
      }
    }
 else {
      throw new RuntimeException("String_Node_Str" + baseDef);
    }
    if (aType != null)     break;
  }
  if (depth == 0 && aType == null) {
    if (nullDefCount == defsOfaBaseList.size()) {
      return NullType.v();
    }
 else {
      throw new RuntimeException("String_Node_Str" + arrayStmt + "String_Node_Str");
    }
  }
 else   return aType;
}

Fixed version (ground truth):
protected Type findArrayType(LocalDefs localDefs,Stmt arrayStmt,int depth,Set<Unit> alreadyVisitedDefs){
  ArrayRef aRef=null;
  if (arrayStmt.containsArrayRef()) {
    aRef=arrayStmt.getArrayRef();
  }
  Local aBase=null;
  if (null == aRef) {
    if (arrayStmt instanceof AssignStmt) {
      AssignStmt stmt=(AssignStmt)arrayStmt;
      aBase=(Local)stmt.getRightOp();
    }
 else {
      throw new RuntimeException("String_Node_Str" + arrayStmt);
    }
  }
 else {
    aBase=(Local)aRef.getBase();
  }
  List<Unit> defsOfaBaseList=localDefs.getDefsOfAt(aBase,arrayStmt);
  if (defsOfaBaseList == null || defsOfaBaseList.isEmpty()) {
    throw new RuntimeException("String_Node_Str" + arrayStmt);
  }
  Type aType=null;
  int nullDefCount=0;
  for (  Unit baseDef : defsOfaBaseList) {
    Debug.printDbg("String_Node_Str",baseDef);
    if (alreadyVisitedDefs.contains(baseDef))     continue;
    Set<Unit> newVisitedDefs=new HashSet<Unit>(alreadyVisitedDefs);
    newVisitedDefs.add(baseDef);
    if (baseDef instanceof AssignStmt) {
      AssignStmt stmt=(AssignStmt)baseDef;
      Value r=stmt.getRightOp();
      if (r instanceof FieldRef) {
        Type t=((FieldRef)r).getFieldRef().type();
        if (t instanceof ArrayType) {
          ArrayType at=(ArrayType)t;
          t=at.getArrayElementType();
        }
        Debug.printDbg("String_Node_Str",t);
        if (depth == 0) {
          aType=t;
          break;
        }
 else {
          return t;
        }
      }
 else       if (r instanceof ArrayRef) {
        ArrayRef ar=(ArrayRef)r;
        if (ar.getType().toString().equals("String_Node_Str") || ar.getType().toString().equals("String_Node_Str")) {
          System.out.println("String_Node_Str" + stmt);
          Type t=findArrayType(localDefs,stmt,++depth,newVisitedDefs);
          if (t instanceof ArrayType) {
            ArrayType at=(ArrayType)t;
            t=at.getArrayElementType();
          }
          if (depth == 0) {
            aType=t;
            break;
          }
 else {
            return t;
          }
        }
 else {
          Debug.printDbg("String_Node_Str",ar.getType().toString());
          ArrayType at=(ArrayType)stmt.getRightOp().getType();
          Type t=at.getArrayElementType();
          if (depth == 0) {
            aType=t;
            break;
          }
 else {
            return t;
          }
        }
      }
 else       if (r instanceof NewArrayExpr) {
        NewArrayExpr expr=(NewArrayExpr)r;
        Type t=expr.getBaseType();
        Debug.printDbg("String_Node_Str",t);
        if (depth == 0) {
          aType=t;
          break;
        }
 else {
          return t;
        }
      }
 else       if (r instanceof CastExpr) {
        Type t=(((CastExpr)r).getCastType());
        Debug.printDbg("String_Node_Str",t);
        if (t instanceof ArrayType) {
          ArrayType at=(ArrayType)t;
          t=at.getArrayElementType();
        }
        if (depth == 0) {
          aType=t;
          break;
        }
 else {
          return t;
        }
      }
 else       if (r instanceof InvokeExpr) {
        Type t=((InvokeExpr)r).getMethodRef().returnType();
        Debug.printDbg("String_Node_Str",t);
        if (t instanceof ArrayType) {
          ArrayType at=(ArrayType)t;
          t=at.getArrayElementType();
        }
        if (depth == 0) {
          aType=t;
          break;
        }
 else {
          return t;
        }
      }
 else       if (r instanceof Local) {
        Debug.printDbg("String_Node_Str",stmt);
        Type t=findArrayType(localDefs,stmt,++depth,newVisitedDefs);
        if (depth == 0) {
          aType=t;
        }
 else {
          aType=t;
        }
      }
 else       if (r instanceof Constant) {
        nullDefCount++;
      }
 else {
        throw new RuntimeException("String_Node_Str" + stmt);
      }
    }
 else     if (baseDef instanceof IdentityStmt) {
      IdentityStmt stmt=(IdentityStmt)baseDef;
      ArrayType at=(ArrayType)stmt.getRightOp().getType();
      Type t=at.getArrayElementType();
      if (depth == 0) {
        aType=t;
        break;
      }
 else {
        return t;
      }
    }
 else {
      throw new RuntimeException("String_Node_Str" + baseDef);
    }
    if (aType != null)     break;
  }
  if (depth == 0 && aType == null) {
    if (nullDefCount == defsOfaBaseList.size()) {
      return NullType.v();
    }
 else {
      throw new RuntimeException("String_Node_Str" + arrayStmt + "String_Node_Str");
    }
  }
 else   return aType;
}