Program: 88564
Project: 88564
Buggy source:
/** 
 * Main.v() entry point for converting list of Instructions to Jimple statements; performs flow analysis, constructs Jimple statements, and fixes jumps.
 * @param constant_pool constant pool of ClassFile.
 * @param this_class constant pool index of the CONSTANT_Class_info object forthis' class.
 * @param clearStacks if <i>true</i> semantic stacks will be deleted afterthe process is complete.
 * @return <i>true</i> if all ok, <i>false</i> if there was an error.
 * @see CFG#jimplify(cp_info[],int)
 * @see Stmt
 */
void jimplify(cp_info constant_pool[],int this_class){
  Code_attribute codeAttribute=method.locate_code_attribute();
  Set handlerInstructions=new ArraySet();
  Map handlerInstructionToException=new HashMap();
  Map instructionToTypeStack;
  Map instructionToPostTypeStack;
{
    buildInsnCFGfromBBCFG();
{
      for (int i=0; i < codeAttribute.exception_table_length; i++) {
        Instruction startIns=codeAttribute.exception_table[i].start_inst;
        Instruction endIns=codeAttribute.exception_table[i].end_inst;
        Instruction handlerIns=codeAttribute.exception_table[i].handler_inst;
        handlerInstructions.add(handlerIns);
{
          int catchType=codeAttribute.exception_table[i].catch_type;
          SootClass exception;
          if (catchType != 0) {
            CONSTANT_Class_info classinfo=(CONSTANT_Class_info)constant_pool[catchType];
            String name=((CONSTANT_Utf8_info)(constant_pool[classinfo.name_index])).convert();
            name=name.replace('/','.');
            exception=cm.getSootClass(name);
          }
 else           exception=cm.getSootClass("String_Node_Str");
          handlerInstructionToException.put(handlerIns,exception);
        }
        if (startIns == endIns)         throw new RuntimeException("String_Node_Str");
        Instruction ins=startIns;
        for (; ; ) {
          Instruction[] succs=ins.succs;
          Instruction[] newsuccs=new Instruction[succs.length + 1];
          System.arraycopy(succs,0,newsuccs,0,succs.length);
          newsuccs[succs.length]=handlerIns;
          ins.succs=newsuccs;
          ins=ins.next;
          if (ins == endIns || ins == null)           break;
        }
      }
    }
  }
  Set reachableInstructions=new HashSet();
{
    LinkedList instructionsToVisit=new LinkedList();
    reachableInstructions.add(firstInstruction);
    instructionsToVisit.addLast(firstInstruction);
    while (!instructionsToVisit.isEmpty()) {
      Instruction ins=(Instruction)instructionsToVisit.removeFirst();
      Instruction[] succs=ins.succs;
      for (int i=0; i < succs.length; i++) {
        Instruction succ=succs[i];
        if (!reachableInstructions.contains(succ)) {
          reachableInstructions.add(succ);
          instructionsToVisit.addLast(succ);
        }
      }
    }
  }
{
    instructionToTypeStack=new HashMap();
    instructionToPostTypeStack=new HashMap();
    Set visitedInstructions=new HashSet();
    List changedInstructions=new ArrayList();
    TypeStack initialTypeStack;
{
      initialTypeStack=TypeStack.v();
    }
{
      instructionToTypeStack.put(firstInstruction,initialTypeStack);
      visitedInstructions.add(firstInstruction);
      changedInstructions.add(firstInstruction);
    }
{
      while (!changedInstructions.isEmpty()) {
        Instruction ins=(Instruction)changedInstructions.get(0);
        changedInstructions.remove(0);
        OutFlow ret=processFlow(ins,(TypeStack)instructionToTypeStack.get(ins),constant_pool);
        instructionToPostTypeStack.put(ins,ret.typeStack);
        Instruction[] successors=ins.succs;
        for (int i=0; i < successors.length; i++) {
          Instruction s=successors[i];
          if (!visitedInstructions.contains(s)) {
            if (handlerInstructions.contains(s)) {
              TypeStack exceptionTypeStack=(TypeStack.v()).push(RefType.v(((SootClass)handlerInstructionToException.get(s)).getName()));
              instructionToTypeStack.put(s,exceptionTypeStack);
            }
 else {
              instructionToTypeStack.put(s,ret.typeStack);
            }
            visitedInstructions.add(s);
            changedInstructions.add(s);
          }
 else {
            TypeStack newTypeStack, oldTypeStack=(TypeStack)instructionToTypeStack.get(s);
            if (handlerInstructions.contains(s)) {
              TypeStack exceptionTypeStack=(TypeStack.v()).push(RefType.v(((SootClass)handlerInstructionToException.get(s)).getName()));
              newTypeStack=exceptionTypeStack;
            }
 else {
              try {
                newTypeStack=ret.typeStack.merge(oldTypeStack);
              }
 catch (              RuntimeException re) {
                G.v().out.println("String_Node_Str" + s);
                throw re;
              }
            }
            if (!newTypeStack.equals(oldTypeStack)) {
              changedInstructions.add(s);
            }
            instructionToTypeStack.put(s,newTypeStack);
          }
        }
      }
    }
  }
{
    Instruction ins=firstInstruction;
    while (ins != null) {
      TypeStack typeStack=(TypeStack)instructionToTypeStack.get(ins);
      ins=ins.next;
    }
  }
{
    BasicBlock b=cfg;
    while (b != null) {
      Instruction ins=b.head;
      b.statements=new ArrayList();
      List blockStatements=b.statements;
      for (; ; ) {
        List statementsForIns=new ArrayList();
        if (reachableInstructions.contains(ins))         generateJimple(ins,(TypeStack)instructionToTypeStack.get(ins),(TypeStack)instructionToPostTypeStack.get(ins),constant_pool,statementsForIns,b);
 else         statementsForIns.add(Jimple.v().newNopStmt());
        if (!statementsForIns.isEmpty()) {
          for (int i=0; i < statementsForIns.size(); i++) {
            units.add(statementsForIns.get(i));
            blockStatements.add(statementsForIns.get(i));
          }
          instructionToFirstStmt.put(ins,statementsForIns.get(0));
          instructionToLastStmt.put(ins,statementsForIns.get(statementsForIns.size() - 1));
        }
        if (ins == b.tail)         break;
        ins=ins.next;
      }
      b=b.next;
    }
  }
  jimpleTargetFixup();
{
    Map targetToHandler=new HashMap();
    for (int i=0; i < codeAttribute.exception_table_length; i++) {
      Instruction startIns=codeAttribute.exception_table[i].start_inst;
      Instruction endIns=codeAttribute.exception_table[i].end_inst;
      Instruction targetIns=codeAttribute.exception_table[i].handler_inst;
      if (!instructionToFirstStmt.containsKey(startIns) || (endIns != null && (!instructionToLastStmt.containsKey(endIns)))) {
        throw new RuntimeException("String_Node_Str");
      }
      if (!instructionToFirstStmt.containsKey(targetIns)) {
        throw new RuntimeException("String_Node_Str");
      }
      SootClass exception;
{
        int catchType=codeAttribute.exception_table[i].catch_type;
        if (catchType != 0) {
          CONSTANT_Class_info classinfo=(CONSTANT_Class_info)constant_pool[catchType];
          String name=((CONSTANT_Utf8_info)(constant_pool[classinfo.name_index])).convert();
          name=name.replace('/','.');
          exception=cm.getSootClass(name);
        }
 else         exception=cm.getSootClass("String_Node_Str");
      }
      Stmt newTarget;
{
        Stmt firstTargetStmt=(Stmt)instructionToFirstStmt.get(targetIns);
        if (targetToHandler.containsKey(firstTargetStmt))         newTarget=(Stmt)targetToHandler.get(firstTargetStmt);
 else {
          Local local=Util.v().getLocalCreatingIfNecessary(listBody,"String_Node_Str",UnknownType.v());
          newTarget=Jimple.v().newIdentityStmt(local,Jimple.v().newCaughtExceptionRef());
          units.insertBefore(newTarget,firstTargetStmt);
          targetToHandler.put(firstTargetStmt,newTarget);
        }
      }
{
        Stmt firstStmt=(Stmt)instructionToFirstStmt.get(startIns);
        Stmt afterEndStmt;
        if (endIns == null) {
          afterEndStmt=(Stmt)units.getLast();
        }
 else {
          afterEndStmt=(Stmt)instructionToLastStmt.get(endIns);
          IdentityStmt catchStart=(IdentityStmt)targetToHandler.get(afterEndStmt);
          if (catchStart != null) {
            if (catchStart != units.getPredOf(afterEndStmt)) {
              throw new IllegalStateException("String_Node_Str");
            }
            afterEndStmt=catchStart;
          }
        }
        Trap trap=Jimple.v().newTrap(exception,firstStmt,afterEndStmt,newTarget);
        listBody.getTraps().add(trap);
      }
    }
  }
  if (Options.v().keep_line_number()) {
    HashMap stmtstags=new HashMap();
    LinkedList startstmts=new LinkedList();
    attribute_info[] attrs=codeAttribute.attributes;
    for (int i=0; i < attrs.length; i++) {
      if (attrs[i] instanceof LineNumberTable_attribute) {
        LineNumberTable_attribute lntattr=(LineNumberTable_attribute)attrs[i];
        for (int j=0; j < lntattr.line_number_table.length; j++) {
          Stmt start_stmt=(Stmt)instructionToFirstStmt.get(lntattr.line_number_table[j].start_inst);
          if (start_stmt != null) {
            LineNumberTag lntag=new LineNumberTag(lntattr.line_number_table[j].line_number);
            stmtstags.put(start_stmt,lntag);
            startstmts.add(start_stmt);
          }
        }
      }
    }
    for (int i=0; i < startstmts.size(); i++) {
      Stmt stmt=(Stmt)startstmts.get(i);
      Tag tag=(Tag)stmtstags.get(stmt);
      stmt.addTag(tag);
      stmt=(Stmt)units.getSuccOf(stmt);
      while (stmt != null && !stmtstags.containsKey(stmt)) {
        stmt.addTag(tag);
        stmt=(Stmt)units.getSuccOf(stmt);
      }
    }
  }
}

Fixed version (ground truth):
/** 
 * Main.v() entry point for converting list of Instructions to Jimple statements; performs flow analysis, constructs Jimple statements, and fixes jumps.
 * @param constant_pool constant pool of ClassFile.
 * @param this_class constant pool index of the CONSTANT_Class_info object forthis' class.
 * @param clearStacks if <i>true</i> semantic stacks will be deleted afterthe process is complete.
 * @return <i>true</i> if all ok, <i>false</i> if there was an error.
 * @see CFG#jimplify(cp_info[],int)
 * @see Stmt
 */
void jimplify(cp_info constant_pool[],int this_class){
  Code_attribute codeAttribute=method.locate_code_attribute();
  Set handlerInstructions=new ArraySet();
  Map handlerInstructionToException=new HashMap();
  Map instructionToTypeStack;
  Map instructionToPostTypeStack;
{
    buildInsnCFGfromBBCFG();
{
      for (int i=0; i < codeAttribute.exception_table_length; i++) {
        Instruction startIns=codeAttribute.exception_table[i].start_inst;
        Instruction endIns=codeAttribute.exception_table[i].end_inst;
        Instruction handlerIns=codeAttribute.exception_table[i].handler_inst;
        handlerInstructions.add(handlerIns);
{
          int catchType=codeAttribute.exception_table[i].catch_type;
          SootClass exception;
          if (catchType != 0) {
            CONSTANT_Class_info classinfo=(CONSTANT_Class_info)constant_pool[catchType];
            String name=((CONSTANT_Utf8_info)(constant_pool[classinfo.name_index])).convert();
            name=name.replace('/','.');
            exception=cm.getSootClass(name);
          }
 else           exception=cm.getSootClass("String_Node_Str");
          handlerInstructionToException.put(handlerIns,exception);
        }
        if (startIns == endIns)         throw new RuntimeException("String_Node_Str");
        Instruction ins=startIns;
        for (; ; ) {
          Instruction[] succs=ins.succs;
          Instruction[] newsuccs=new Instruction[succs.length + 1];
          System.arraycopy(succs,0,newsuccs,0,succs.length);
          newsuccs[succs.length]=handlerIns;
          ins.succs=newsuccs;
          ins=ins.next;
          if (ins == endIns || ins == null)           break;
        }
      }
    }
  }
  Set reachableInstructions=new HashSet();
{
    LinkedList instructionsToVisit=new LinkedList();
    reachableInstructions.add(firstInstruction);
    instructionsToVisit.addLast(firstInstruction);
    while (!instructionsToVisit.isEmpty()) {
      Instruction ins=(Instruction)instructionsToVisit.removeFirst();
      Instruction[] succs=ins.succs;
      for (int i=0; i < succs.length; i++) {
        Instruction succ=succs[i];
        if (!reachableInstructions.contains(succ)) {
          reachableInstructions.add(succ);
          instructionsToVisit.addLast(succ);
        }
      }
    }
  }
{
    instructionToTypeStack=new HashMap();
    instructionToPostTypeStack=new HashMap();
    Set visitedInstructions=new HashSet();
    List changedInstructions=new ArrayList();
    TypeStack initialTypeStack;
{
      initialTypeStack=TypeStack.v();
    }
{
      instructionToTypeStack.put(firstInstruction,initialTypeStack);
      visitedInstructions.add(firstInstruction);
      changedInstructions.add(firstInstruction);
    }
{
      while (!changedInstructions.isEmpty()) {
        Instruction ins=(Instruction)changedInstructions.get(0);
        changedInstructions.remove(0);
        OutFlow ret=processFlow(ins,(TypeStack)instructionToTypeStack.get(ins),constant_pool);
        instructionToPostTypeStack.put(ins,ret.typeStack);
        Instruction[] successors=ins.succs;
        for (int i=0; i < successors.length; i++) {
          Instruction s=successors[i];
          if (!visitedInstructions.contains(s)) {
            if (handlerInstructions.contains(s)) {
              TypeStack exceptionTypeStack=(TypeStack.v()).push(RefType.v(((SootClass)handlerInstructionToException.get(s)).getName()));
              instructionToTypeStack.put(s,exceptionTypeStack);
            }
 else {
              instructionToTypeStack.put(s,ret.typeStack);
            }
            visitedInstructions.add(s);
            changedInstructions.add(s);
          }
 else {
            TypeStack newTypeStack, oldTypeStack=(TypeStack)instructionToTypeStack.get(s);
            if (handlerInstructions.contains(s)) {
              TypeStack exceptionTypeStack=(TypeStack.v()).push(RefType.v(((SootClass)handlerInstructionToException.get(s)).getName()));
              newTypeStack=exceptionTypeStack;
            }
 else {
              try {
                newTypeStack=ret.typeStack.merge(oldTypeStack);
              }
 catch (              RuntimeException re) {
                G.v().out.println("String_Node_Str" + s);
                throw re;
              }
            }
            if (!newTypeStack.equals(oldTypeStack)) {
              changedInstructions.add(s);
            }
            instructionToTypeStack.put(s,newTypeStack);
          }
        }
      }
    }
  }
{
    Instruction ins=firstInstruction;
    while (ins != null) {
      TypeStack typeStack=(TypeStack)instructionToTypeStack.get(ins);
      ins=ins.next;
    }
  }
{
    BasicBlock b=cfg;
    while (b != null) {
      Instruction ins=b.head;
      b.statements=new ArrayList();
      List blockStatements=b.statements;
      for (; ; ) {
        List statementsForIns=new ArrayList();
        if (reachableInstructions.contains(ins))         generateJimple(ins,(TypeStack)instructionToTypeStack.get(ins),(TypeStack)instructionToPostTypeStack.get(ins),constant_pool,statementsForIns,b);
 else         statementsForIns.add(Jimple.v().newNopStmt());
        if (!statementsForIns.isEmpty()) {
          for (int i=0; i < statementsForIns.size(); i++) {
            units.add(statementsForIns.get(i));
            blockStatements.add(statementsForIns.get(i));
          }
          instructionToFirstStmt.put(ins,statementsForIns.get(0));
          instructionToLastStmt.put(ins,statementsForIns.get(statementsForIns.size() - 1));
        }
        if (ins == b.tail)         break;
        ins=ins.next;
      }
      b=b.next;
    }
  }
  jimpleTargetFixup();
{
    Map targetToHandler=new HashMap();
    for (int i=0; i < codeAttribute.exception_table_length; i++) {
      Instruction startIns=codeAttribute.exception_table[i].start_inst;
      Instruction endIns=codeAttribute.exception_table[i].end_inst;
      Instruction targetIns=codeAttribute.exception_table[i].handler_inst;
      if (!instructionToFirstStmt.containsKey(startIns) || (endIns != null && (!instructionToLastStmt.containsKey(endIns)))) {
        throw new RuntimeException("String_Node_Str");
      }
      if (!instructionToFirstStmt.containsKey(targetIns)) {
        throw new RuntimeException("String_Node_Str");
      }
      SootClass exception;
{
        int catchType=codeAttribute.exception_table[i].catch_type;
        if (catchType != 0) {
          CONSTANT_Class_info classinfo=(CONSTANT_Class_info)constant_pool[catchType];
          String name=((CONSTANT_Utf8_info)(constant_pool[classinfo.name_index])).convert();
          name=name.replace('/','.');
          exception=cm.getSootClass(name);
        }
 else         exception=cm.getSootClass("String_Node_Str");
      }
      Stmt newTarget;
{
        Stmt firstTargetStmt=(Stmt)instructionToFirstStmt.get(targetIns);
        if (targetToHandler.containsKey(firstTargetStmt))         newTarget=(Stmt)targetToHandler.get(firstTargetStmt);
 else {
          Local local=Util.v().getLocalCreatingIfNecessary(listBody,"String_Node_Str",UnknownType.v());
          newTarget=Jimple.v().newIdentityStmt(local,Jimple.v().newCaughtExceptionRef());
          units.insertBefore(newTarget,firstTargetStmt);
          instructionToFirstStmt.put(targetIns,newTarget);
          targetToHandler.put(firstTargetStmt,newTarget);
        }
      }
{
        Stmt firstStmt=(Stmt)instructionToFirstStmt.get(startIns);
        Stmt afterEndStmt;
        if (endIns == null) {
          afterEndStmt=(Stmt)units.getLast();
        }
 else {
          afterEndStmt=(Stmt)instructionToLastStmt.get(endIns);
          IdentityStmt catchStart=(IdentityStmt)targetToHandler.get(afterEndStmt);
          if (catchStart != null) {
            if (catchStart != units.getPredOf(afterEndStmt)) {
              throw new IllegalStateException("String_Node_Str");
            }
            afterEndStmt=catchStart;
          }
        }
        Trap trap=Jimple.v().newTrap(exception,firstStmt,afterEndStmt,newTarget);
        listBody.getTraps().add(trap);
      }
    }
  }
  if (Options.v().keep_line_number()) {
    HashMap stmtstags=new HashMap();
    LinkedList startstmts=new LinkedList();
    attribute_info[] attrs=codeAttribute.attributes;
    for (int i=0; i < attrs.length; i++) {
      if (attrs[i] instanceof LineNumberTable_attribute) {
        LineNumberTable_attribute lntattr=(LineNumberTable_attribute)attrs[i];
        for (int j=0; j < lntattr.line_number_table.length; j++) {
          Stmt start_stmt=(Stmt)instructionToFirstStmt.get(lntattr.line_number_table[j].start_inst);
          if (start_stmt != null) {
            LineNumberTag lntag=new LineNumberTag(lntattr.line_number_table[j].line_number);
            stmtstags.put(start_stmt,lntag);
            startstmts.add(start_stmt);
          }
        }
      }
    }
    for (int i=0; i < startstmts.size(); i++) {
      Stmt stmt=(Stmt)startstmts.get(i);
      Tag tag=(Tag)stmtstags.get(stmt);
      stmt.addTag(tag);
      stmt=(Stmt)units.getSuccOf(stmt);
      while (stmt != null && !stmtstags.containsKey(stmt)) {
        stmt.addTag(tag);
        stmt=(Stmt)units.getSuccOf(stmt);
      }
    }
  }
}