public static int getSolvedPC(MJIEnv env, int objRef) { PathCondition pc = getPC(env); if (pc != null) { pc.solve(); return env.newString(pc.toString()); } return env.newString(""); }
@Override public Instruction execute(ThreadInfo th) { IntegerExpression sym_lval = (IntegerExpression) th.getModifiableTopFrame().getLongOperandAttr(); if (sym_lval == null) { return super.execute(th); } else { // throw new RuntimeException("## Error: symbolic L2F not yet hanled "); // here we get a hold of the current path condition and // add an extra mixed constraint sym_dval==sym_ival ChoiceGenerator<?> cg; if (!th.isFirstStepInsn()) { // first time around cg = new PCChoiceGenerator(1); // only one choice th.getVM().getSystemState().setNextChoiceGenerator(cg); return this; } else { // this is what really returns results cg = th.getVM().getSystemState().getChoiceGenerator(); assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; } // get the path condition from the // previous choice generator of the same type PathCondition pc; ChoiceGenerator<?> prev_cg = cg.getPreviousChoiceGenerator(); while (!((prev_cg == null) || (prev_cg instanceof PCChoiceGenerator))) { prev_cg = prev_cg.getPreviousChoiceGenerator(); } if (prev_cg == null) pc = new PathCondition(); // TODO: handling of preconditions needs to be changed else pc = ((PCChoiceGenerator) prev_cg).getCurrentPC(); assert pc != null; StackFrame sf = th.getModifiableTopFrame(); sf.popLong(); sf.push(0, false); // for symbolic expressions, the concrete value does not matter SymbolicReal sym_fval = new SymbolicReal(); sf.setOperandAttr(sym_fval); pc._addDet(Comparator.EQ, sym_fval, sym_lval); if (!pc.simplify()) { // not satisfiable th.getVM().getSystemState().setIgnored(true); } else { // pc.solve(); ((PCChoiceGenerator) cg).setCurrentPC(pc); // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); } // System.out.println("Execute L2F: " + sf.getLongOperandAttr()); return getNext(th); } }
// the purpose of this method is to set the PCheap to the "eq null" constraint for the input // specified w/ stringRef public static int makeSymbolicNull(MJIEnv env, int objRef, int stringRef) { // introduce a heap choice generator for the element in the heap ThreadInfo ti = env.getVM().getCurrentThread(); SystemState ss = env.getVM().getSystemState(); ChoiceGenerator<?> cg; if (!ti.isFirstStepInsn()) { cg = new HeapChoiceGenerator(1); // new ss.setNextChoiceGenerator(cg); env.repeatInvocation(); return -1; // not used anyways } // else this is what really returns results cg = ss.getChoiceGenerator(); assert (cg instanceof HeapChoiceGenerator) : "expected HeapChoiceGenerator, got: " + cg; // see if there were more inputs added before ChoiceGenerator<?> prevHeapCG = cg.getPreviousChoiceGenerator(); while (!((prevHeapCG == null) || (prevHeapCG instanceof HeapChoiceGenerator))) { prevHeapCG = prevHeapCG.getPreviousChoiceGenerator(); } PathCondition pcHeap; SymbolicInputHeap symInputHeap; if (prevHeapCG == null) { pcHeap = new PathCondition(); symInputHeap = new SymbolicInputHeap(); } else { pcHeap = ((HeapChoiceGenerator) prevHeapCG).getCurrentPCheap(); symInputHeap = ((HeapChoiceGenerator) prevHeapCG).getCurrentSymInputHeap(); } String name = env.getStringObject(stringRef); String refChain = name + "[-1]"; // why is the type used here? should use the name of the field instead SymbolicInteger newSymRef = new SymbolicInteger(refChain); // create new HeapNode based on above info // update associated symbolic input heap pcHeap._addDet(Comparator.EQ, newSymRef, new IntegerConstant(-1)); ((HeapChoiceGenerator) cg).setCurrentPCheap(pcHeap); ((HeapChoiceGenerator) cg).setCurrentSymInputHeap(symInputHeap); // System.out.println(">>>>>>>>>>>> initial pcHeap: " + pcHeap.toString()); return -1; }
private void exec(String name, Search search) { VM vm = search.getVM(); PCChoiceGenerator choiceGenerator = vm.getLastChoiceGeneratorOfType(PCChoiceGenerator.class); if (choiceGenerator != null) { PathCondition pc = choiceGenerator.getCurrentPC(); if (search.getErrors().size() < 0) { return; } Property property = search.getLastError().getProperty(); if (!property.getErrorMessage().contains(AssertionError.class.getCanonicalName())) { pc.header = pc.header.not(); } /* * if (property instanceof NoUncaughtExceptionsProperty) { * NoUncaughtExceptionsProperty noUncaughtExceptionsProperty = * (NoUncaughtExceptionsProperty) property; String clName = * noUncaughtExceptionsProperty * .getUncaughtExceptionInfo().getCauseClassname(); * if(!clName.equals(AssertionError.class.getCanonicalName())) { * * } System.out.println(clName); } */ // /* * if (instruction instanceof IfInstruction) { if * (((IfInstruction) instruction).getConditionValue()) { * pc.solve(); * * } } */ pc.solve(); Map<String, Object> varsVals = new HashMap<String, Object>(); pc.header.getVarVals(varsVals); if (varsVals.containsKey("guess_fix")) { this.result = varsVals.get("guess_fix"); if (processor.getType().equals(Boolean.class)) { this.result = this.result.equals(1); } } logger.debug("JPF Result " + this.result); } }
@Override public void advance() { super.advance(); System.err.println("AtomBuchiCG.advance: " + toString()); if (originalPC == null) { return; } PathCondition guardPC = originalPC.make_copy(); for (Literal<String> l : node.getOutgoingEdges().get(index).getGuard()) { Atom a = stringToAtom(l.getAtom()); Set<Constraint> constraints = a.getConstraints(); System.err.println( "AtomBuchiCG.advance: for guard=" + l.getAtom() + ", atom=" + a + ", atom.text=" + a.getText() + ", constraints=" + constraints); if (constraints == null) { continue; } for (Constraint c : constraints) { if (l.isNegated()) { guardPC.prependUnlessRepeated(c.not()); } else { guardPC.prependUnlessRepeated(c); } } } setPC(guardPC); }
@Override public Instruction execute(SystemState ss, KernelState ks, ThreadInfo ti) { StackFrame sf = ti.getTopFrame(); IntegerExpression sym_v1 = (IntegerExpression) sf.getOperandAttr(1); IntegerExpression sym_v2 = (IntegerExpression) sf.getOperandAttr(0); if ((sym_v1 == null) && (sym_v2 == null)) { // both conditions are concrete // System.out.println("Execute IF_ICMPEQ: The conditions are concrete"); return super.execute(ss, ks, ti); } else { // at least one condition is symbolic ChoiceGenerator<?> cg; if (!ti.isFirstStepInsn()) { // first time around cg = new PCChoiceGenerator(2); ss.setNextChoiceGenerator(cg); return this; } else { // this is what really returns results cg = ss.getChoiceGenerator(); assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; conditionValue = (Integer) cg.getNextChoice() == 0 ? false : true; } int v2 = ti.pop(); int v1 = ti.pop(); // System.out.println("Execute IF_ICMPEQ: "+ conditionValue); PathCondition pc; // pc is updated with the pc stored in the choice generator above // get the path condition from the // previous choice generator of the same type ChoiceGenerator<?> prev_cg = cg.getPreviousChoiceGenerator(); while (!((prev_cg == null) || (prev_cg instanceof PCChoiceGenerator))) { prev_cg = prev_cg.getPreviousChoiceGenerator(); } if (prev_cg == null) pc = new PathCondition(); else pc = ((PCChoiceGenerator) prev_cg).getCurrentPC(); assert pc != null; if (conditionValue) { if (sym_v1 != null) { if (sym_v2 != null) { // both are symbolic values pc._addDet(Comparator.EQ, sym_v1, sym_v2); } else pc._addDet(Comparator.EQ, sym_v1, v2); } else pc._addDet(Comparator.EQ, v1, sym_v2); if (!pc.simplify()) { // not satisfiable ss.setIgnored(true); } else { // pc.solve(); ((PCChoiceGenerator) cg).setCurrentPC(pc); // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); } return getTarget(); } else { if (sym_v1 != null) { if (sym_v2 != null) { // both are symbolic values pc._addDet(Comparator.NE, sym_v1, sym_v2); } else pc._addDet(Comparator.NE, sym_v1, v2); } else pc._addDet(Comparator.NE, v1, sym_v2); if (!pc.simplify()) { // not satisfiable ss.setIgnored(true); } else { // pc.solve(); ((PCChoiceGenerator) cg).setCurrentPC(pc); // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); } return getNext(ti); } } }
@SuppressWarnings("deprecation") @Override public Instruction execute(ThreadInfo ti) { StackFrame sf = ti.getModifiableTopFrame(); IntegerExpression sym_v = (IntegerExpression) sf.getOperandAttr(); if (sym_v == null) { // the condition is concrete return super.execute(ti); } else { // the condition is symbolic ChoiceGenerator<?> cg; if (!ti.isFirstStepInsn()) { // first time around cg = new PCChoiceGenerator(matches.length + 1); ((PCChoiceGenerator) cg).setOffset(this.position); ((PCChoiceGenerator) cg).setMethodName(this.getMethodInfo().getCompleteName()); ti.getVM().getSystemState().setNextChoiceGenerator(cg); return this; } else { // this is what really returns results cg = ti.getVM().getSystemState().getChoiceGenerator(); assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; } sym_v = (IntegerExpression) sf.getOperandAttr(); sf.pop(); PathCondition pc; // pc is updated with the pc stored in the choice generator above // get the path condition from the // previous choice generator of the same type // TODO: could be optimized to not do this for each choice ChoiceGenerator<?> prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); if (prev_cg == null) pc = new PathCondition(); else pc = ((PCChoiceGenerator) prev_cg).getCurrentPC(); assert pc != null; int idx = (Integer) cg.getNextChoice(); if (idx == matches.length) { // default branch lastIdx = DEFAULT; for (int i = 0; i < matches.length; i++) pc._addDet(Comparator.NE, sym_v, matches[i]); if (!pc.simplify()) { // not satisfiable ti.getVM().getSystemState().setIgnored(true); } else { // pc.solve(); ((PCChoiceGenerator) cg).setCurrentPC(pc); // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); } return mi.getInstructionAt(target); } else { lastIdx = idx; // System.out.println("index "+idx); pc._addDet(Comparator.EQ, sym_v, matches[idx]); // System.out.println(sym_v + "eq"+ matches[idx]); // System.out.println("pc after "+pc); if (!pc.simplify()) { // not satisfiable ti.getVM().getSystemState().setIgnored(true); } else { // pc.solve(); ((PCChoiceGenerator) cg).setCurrentPC(pc); // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); } return mi.getInstructionAt(targets[idx]); } } }
@Override public Instruction execute(ThreadInfo th) { StackFrame sf = th.getModifiableTopFrame(); IntegerExpression sym_v1 = (IntegerExpression) sf.getOperandAttr(0); IntegerExpression sym_v2 = (IntegerExpression) sf.getOperandAttr(1); int v1, v2; if (sym_v1 == null && sym_v2 == null) return super.execute(th); // we'll still do the concrete execution // result is symbolic if (sym_v1 == null && sym_v2 != null) { v1 = sf.pop(); v2 = sf.pop(); if (v1 == 0) return th.createAndThrowException("java.lang.ArithmeticException", "div by 0"); sf.push(0, false); IntegerExpression result = sym_v2._div(v1); sf.setOperandAttr(result); return getNext(th); } // div by zero check affects path condition // sym_v1 is non-null and should be checked against zero ChoiceGenerator<?> cg; boolean condition; if (!th.isFirstStepInsn()) { // first time around cg = new PCChoiceGenerator(2); ((PCChoiceGenerator) cg).setOffset(this.position); ((PCChoiceGenerator) cg).setMethodName(this.getMethodInfo().getFullName()); th.getVM().setNextChoiceGenerator(cg); return this; } else { // this is what really returns results cg = th.getVM().getChoiceGenerator(); assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; condition = (Integer) cg.getNextChoice() == 0 ? false : true; } v1 = sf.pop(); v2 = sf.pop(); sf.push(0, false); PathCondition pc; ChoiceGenerator<?> prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); if (prev_cg == null) pc = new PathCondition(); else pc = ((PCChoiceGenerator) prev_cg).getCurrentPC(); assert pc != null; if (condition) { // check div by zero pc._addDet(Comparator.EQ, sym_v1, 0); if (pc.simplify()) { // satisfiable ((PCChoiceGenerator) cg).setCurrentPC(pc); return th.createAndThrowException("java.lang.ArithmeticException", "div by 0"); } else { th.getVM().getSystemState().setIgnored(true); return getNext(th); } } else { pc._addDet(Comparator.NE, sym_v1, 0); if (pc.simplify()) { // satisfiable ((PCChoiceGenerator) cg).setCurrentPC(pc); // set the result IntegerExpression result; if (sym_v2 != null) result = sym_v2._div(sym_v1); else result = sym_v1._div_reverse(v2); sf = th.getModifiableTopFrame(); sf.setOperandAttr(result); return getNext(th); } else { th.getVM().getSystemState().setIgnored(true); return getNext(th); } } }
@Override public Boolean solve() { for (int i = 0; i < numSolvers; i++) { try{ if (ignoredSolvers[i]) { System.out.println("ignoring solver " + probs[i].toString() + ": unsupported operation"); } else { Boolean s = probs[i].solve(); if (i > 0 && s != null && s) { // skip coral Env check = this.check(intVars, realVars, i); boolean s2 = (check.getResult() == Result.SAT) ? true : false; if (s2) { solutions[i] = s; } else { System.out .println("## Symlib of Coral does not agree with " + i + " posted solution"); solutions[i] = false; } } else { solutions[i] = (s == null) ? false : s; } // if (s == null) { // solutions[i] = false; // } else { // solutions[i] = s; // } } } catch(Exception _){ solutions[i] = false; System.out.println("Solver " + i + " threw an exception"); _.printStackTrace(); } if (alwaysPrint) { System.out.println("Solver " + Integer.toString(i) + ": " + Boolean.toString(solutions[i])); } } // matrix update solvingDiff.update(solutions); if (!alwaysPrint) { boolean first = solutions[0]; boolean print = false; for (int j = 1; j < numSolvers; j++) { if (solutions[j] != first) { print = true; break; } } if (print) { System.out.println("---- SOLVERS DISAGREE! ------"); System.out.println(p.toString()); for (int i = 0; i < numSolvers; i++) { System.out.println(" Solver " + Integer.toString(i) + ": " + Boolean.toString(solutions[i])); } } } for (int i = 0; i < numSolvers; i++){ if(solutions[i]){ selected = i; break; } } return solutions[selected]; }
@Override public Instruction execute(ThreadInfo ti) { // We may need to add the case where we have a smybolic index and a concrete array IntegerExpression indexAttr = null; ArrayExpression arrayAttr = null; StackFrame frame = ti.getModifiableTopFrame(); int arrayRef = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore if (arrayRef == MJIEnv.NULL) { return ti.createAndThrowException("java.lang.NullPointerException"); } // Retrieve the array expression if it was previously in the pathcondition, and store it as an // array attr PCChoiceGenerator temp_cg = (PCChoiceGenerator) ti.getVM().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); if (temp_cg != null) { if (temp_cg .getCurrentPC() .arrayExpressions .containsKey(ti.getElementInfo(ti.getModifiableTopFrame().peek(2)).toString())) { ti.getModifiableTopFrame() .setOperandAttr( 2, temp_cg .getCurrentPC() .arrayExpressions .get(ti.getElementInfo(ti.getModifiableTopFrame().peek(2)).toString())); } } // If only the value is symbolic, we use the concrete instruction if (peekArrayAttr(ti) == null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { // In this case, the array isn't symbolic if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { return super.execute(ti); } } ChoiceGenerator<?> cg; if (!ti.isFirstStepInsn()) { // first time around cg = new PCChoiceGenerator(3); ((PCChoiceGenerator) cg).setOffset(this.position); ((PCChoiceGenerator) cg).setMethodName(this.getMethodInfo().getFullName()); ti.getVM().setNextChoiceGenerator(cg); return this; } else { // this is what really returns results cg = ti.getVM().getChoiceGenerator(); assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; } PathCondition pc; ChoiceGenerator<?> prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); if (prev_cg == null) pc = new PathCondition(); else pc = ((PCChoiceGenerator) prev_cg).getCurrentPC(); assert pc != null; if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { int index = ti.getTopFrame().peek(1); indexAttr = new IntegerConstant(index); } else { indexAttr = (IntegerExpression) peekIndexAttr(ti); } assert (indexAttr != null) : "indexAttr shouldn't be null in FASTORE instruction"; if (peekArrayAttr(ti) == null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { // In this case, the array isn't symbolic if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { return super.execute(ti); } else { // We create a symbolic array out of the concrete array ElementInfo arrayInfo = ti.getElementInfo(arrayRef); arrayAttr = ArrayExpression.create(arrayInfo.toString(), arrayInfo.arrayLength()); // We add the constraints about all the elements of the array for (int i = 0; i < arrayInfo.arrayLength(); i++) { float arrValue = arrayInfo.getFloatElement(i); pc._addDet( Comparator.EQ, new SelectExpression(arrayAttr, new IntegerConstant(i)), new RealConstant(arrValue)); } } } else { arrayAttr = (ArrayExpression) peekArrayAttr(ti); } assert (arrayAttr != null) : "arrayAttr shouldn't be null in FASTORE instruction"; if ((Integer) cg.getNextChoice() == 1) { // check bounds of the index pc._addDet(Comparator.GE, indexAttr, arrayAttr.length); if (pc.simplify()) { // satisfiable ((PCChoiceGenerator) cg).setCurrentPC(pc); return ti.createAndThrowException( "java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds"); } else { ti.getVM().getSystemState().setIgnored(true); return getNext(ti); } } else if ((Integer) cg.getNextChoice() == 2) { pc._addDet(Comparator.LT, indexAttr, new IntegerConstant(0)); if (pc.simplify()) { // satisfiable ((PCChoiceGenerator) cg).setCurrentPC(pc); return ti.createAndThrowException( "java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds"); } else { ti.getVM().getSystemState().setIgnored(true); return getNext(ti); } } else { pc._addDet(Comparator.LT, indexAttr, arrayAttr.length); pc._addDet(Comparator.GE, indexAttr, new IntegerConstant(0)); if (pc.simplify()) { // satisfiable ((PCChoiceGenerator) cg).setCurrentPC(pc); RealExpression sym_value = null; if (frame.getOperandAttr(0) == null || !(frame.getOperandAttr(0) instanceof RealExpression)) { float value = frame.popFloat(); sym_value = new RealConstant(value); } else { // The value is symbolic. sym_value = (RealExpression) frame.getOperandAttr(0); frame.popFloat(); } // We create a new arrayAttr, and inherits information from the previous attribute ArrayExpression newArrayAttr = new ArrayExpression(arrayAttr); frame.pop(2); // We pop the array and the index RealStoreExpression se = new RealStoreExpression(arrayAttr, indexAttr, sym_value); pc._addDet(Comparator.EQ, se, newArrayAttr); pc.arrayExpressions.put(newArrayAttr.getRootName(), newArrayAttr); return getNext(ti); } else { ti.getVM().getSystemState().setIgnored(true); return getNext(ti); } } }
public AtomBuchiCG(Node<String> n) { super(n); originalPC = PathCondition.getPC(JVM.getVM()); }
public static void makeFieldsSymbolic(MJIEnv env, int objRef, int stringRef, int objvRef) { // makes all the fields of obj v symbolic and adds obj v to the symbolic heap to kick off lazy // initialization if (objvRef == -1) throw new RuntimeException("## Error: null object"); // introduce a heap choice generator for the element in the heap ThreadInfo ti = env.getVM().getCurrentThread(); SystemState ss = env.getVM().getSystemState(); ChoiceGenerator<?> cg; if (!ti.isFirstStepInsn()) { cg = new HeapChoiceGenerator(1); // new ss.setNextChoiceGenerator(cg); env.repeatInvocation(); return; // not used anyways } // else this is what really returns results cg = ss.getChoiceGenerator(); assert (cg instanceof HeapChoiceGenerator) : "expected HeapChoiceGenerator, got: " + cg; // see if there were more inputs added before ChoiceGenerator<?> prevHeapCG = cg.getPreviousChoiceGenerator(); while (!((prevHeapCG == null) || (prevHeapCG instanceof HeapChoiceGenerator))) { prevHeapCG = prevHeapCG.getPreviousChoiceGenerator(); } PathCondition pcHeap; SymbolicInputHeap symInputHeap; if (prevHeapCG == null) { pcHeap = new PathCondition(); symInputHeap = new SymbolicInputHeap(); } else { pcHeap = ((HeapChoiceGenerator) prevHeapCG).getCurrentPCheap(); symInputHeap = ((HeapChoiceGenerator) prevHeapCG).getCurrentSymInputHeap(); } // set all the fields to be symbolic ClassInfo ci = env.getClassInfo(objvRef); FieldInfo[] fields = ci.getDeclaredInstanceFields(); FieldInfo[] staticFields = ci.getDeclaredStaticFields(); String name = env.getStringObject(stringRef); String refChain = name + "[" + objvRef + "]"; // why is the type used here? should use the name of the field instead SymbolicInteger newSymRef = new SymbolicInteger(refChain); // ElementInfo eiRef = DynamicArea.getHeap().get(objvRef); ElementInfo eiRef = JVM.getVM().getHeap().get(objvRef); Helper.initializeInstanceFields(fields, eiRef, refChain); Helper.initializeStaticFields(staticFields, ci, ti); // create new HeapNode based on above info // update associated symbolic input heap ClassInfo typeClassInfo = eiRef.getClassInfo(); HeapNode n = new HeapNode(objvRef, typeClassInfo, newSymRef); symInputHeap._add(n); pcHeap._addDet(Comparator.NE, newSymRef, new IntegerConstant(-1)); ((HeapChoiceGenerator) cg).setCurrentPCheap(pcHeap); ((HeapChoiceGenerator) cg).setCurrentSymInputHeap(symInputHeap); // System.out.println(">>>>>>>>>>>> initial pcHeap: " + pcHeap.toString()); return; }
public static HelperResult addNewArrayHeapNode( ClassInfo typeClassInfo, ThreadInfo ti, Object attr, PathCondition pcHeap, SymbolicInputHeap symInputHeap, int numSymRefs, HeapNode[] prevSymRefs, boolean setShared, IntegerExpression indexAttr, int arrayRef) { int daIndex = ti.getHeap().newObject(typeClassInfo, ti).getObjectRef(); ti.getHeap().registerPinDown(daIndex); String refChain = ((ArrayExpression) attr) .getName(); // + "[" + daIndex + "]"; // do we really need to add daIndex here? SymbolicInteger newSymRef = new SymbolicInteger(refChain); ElementInfo eiRef = ti.getModifiableElementInfo(daIndex); // ti.getElementInfo(daIndex); // TODO to review! if (setShared) { eiRef.setShared(ti, true); // ?? } // daIndex.getObjectRef() -> number // neha: this change allows all the fields in the class hierarchy of the // object to be initialized as symbolic and not just its instance fields int numOfFields = eiRef.getNumberOfFields(); FieldInfo[] fields = new FieldInfo[numOfFields]; for (int fieldIndex = 0; fieldIndex < numOfFields; fieldIndex++) { fields[fieldIndex] = eiRef.getFieldInfo(fieldIndex); } Helper.initializeInstanceFields(fields, eiRef, refChain); // neha: this change allows all the static fields in the class hierarchy // of the object to be initialized as symbolic and not just its immediate // static fields ClassInfo superClass = typeClassInfo; while (superClass != null) { FieldInfo[] staticFields = superClass.getDeclaredStaticFields(); Helper.initializeStaticFields(staticFields, superClass, ti); superClass = superClass.getSuperClass(); } // Put symbolic array in PC if we create a new array. if (typeClassInfo.isArray()) { String typeClass = typeClassInfo.getType(); ArrayExpression arrayAttr = null; if (typeClass.charAt(1) != 'L') { arrayAttr = new ArrayExpression(eiRef.toString()); } else { arrayAttr = new ArrayExpression(eiRef.toString(), typeClass.substring(2, typeClass.length() - 1)); } ti.getVM() .getLastChoiceGeneratorOfType(PCChoiceGenerator.class) .getCurrentPC() .arrayExpressions .put(eiRef.toString(), arrayAttr); } // create new HeapNode based on above info // update associated symbolic input heap ArrayHeapNode n = new ArrayHeapNode(daIndex, typeClassInfo, newSymRef, indexAttr, arrayRef); symInputHeap._add(n); pcHeap._addDet(Comparator.NE, newSymRef, new IntegerConstant(-1)); pcHeap._addDet(Comparator.EQ, newSymRef, new IntegerConstant(numSymRefs)); for (int i = 0; i < numSymRefs; i++) pcHeap._addDet(Comparator.NE, n.getSymbolic(), prevSymRefs[i].getSymbolic()); HelperResult result = new HelperResult(n, daIndex); return result; }