// edge.getSource().getId() + " has no value number");
return tmpFact;
}
ValueNumber instanceOfValueNumber = check.getValueNumber();
ValueNumberFrame vnaFrame = valueNumberDataflow.getStartFact(edge.getTarget());
if (!vnaFrame.isValid()) {
return tmpFact;
}
Type instanceOfType = check.getType();
if (!(instanceOfType instanceof ReferenceType || instanceOfType instanceof NullType)) {
return tmpFact;
}
short branchOpcode = edge.getSource().getLastInstruction().getInstruction().getOpcode();
int edgeType = edge.getType();
int numSlots = Math.min(fact.getNumSlots(), vnaFrame.getNumSlots());
if ((edgeType == EdgeTypes.IFCMP_EDGE && (branchOpcode == Constants.IFNE || branchOpcode == Constants.IFGT || branchOpcode == Constants.IFNULL))
|| (edgeType == EdgeTypes.FALL_THROUGH_EDGE && (branchOpcode == Constants.IFEQ || branchOpcode == Constants.IFLE || branchOpcode == Constants.IFNONNULL))) {
// System.out.println("Successful check on edge " + edge);
// Successful instanceof check.
for (int i = 0; i < numSlots; ++i) {
if (!vnaFrame.getValue(i).equals(instanceOfValueNumber)) {
continue;
}
Type checkedType = fact.getValue(i);
if (!(checkedType instanceof ReferenceType)) {
continue;
}
// Only refine the type if the cast is feasible: i.e., a
// downcast.
// Otherwise, just set it to TOP.
try {
boolean guaranteed = Hierarchy.isSubtype((ReferenceType) checkedType, (ReferenceType) instanceOfType);
if (guaranteed) {
continue;
}
boolean feasibleCheck = instanceOfType.equals(NullType.instance())
|| Hierarchy.isSubtype((ReferenceType) instanceOfType, (ReferenceType) checkedType);
if (!feasibleCheck && instanceOfType instanceof ObjectType && checkedType instanceof ObjectType) {
double v = Analyze.deepInstanceOf(((ObjectType) instanceOfType).getClassName(),
((ObjectType) checkedType).getClassName());
if (v > 0.0) {
feasibleCheck = true;
}
}
tmpFact = modifyFrame(fact, tmpFact);
if (feasibleCheck) {
tmpFact.setValue(i, instanceOfType);
} else {
tmpFact.setTop();
return tmpFact;
}
} catch (ClassNotFoundException e) {
lookupFailureCallback.reportMissingClass(e);
return tmpFact;
}
}
} else if (!instanceOfType.equals(NullType.instance())) {
for (int i = 0; i < numSlots; ++i) {
if (!vnaFrame.getValue(i).equals(instanceOfValueNumber)) {
continue;
}
Type checkedType = fact.getValue(i);
if (!(checkedType instanceof ReferenceType)) {