fixes to pointer analysis to handle languages that have a separate 'null' type for which no one should be reading/writing fields
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@1322 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
e3b01a2fab
commit
d6a5efccc1
|
@ -22,6 +22,10 @@ public interface Language {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isNullType(TypeReference type) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
Atom getName();
|
||||
|
@ -30,4 +34,6 @@ public interface Language {
|
|||
|
||||
TypeReference getConstantType(Object o);
|
||||
|
||||
}
|
||||
boolean isNullType(TypeReference type);
|
||||
|
||||
}
|
||||
|
|
|
@ -16,12 +16,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IField;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.NewSiteReference;
|
||||
import com.ibm.wala.classLoader.SyntheticClass;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.fixedpoint.impl.UnaryOperator;
|
||||
import com.ibm.wala.fixpoint.IVariable;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
|
@ -659,6 +654,12 @@ public abstract class PropagationCallGraphBuilder implements CallGraphBuilder {
|
|||
return false;
|
||||
}
|
||||
|
||||
public static boolean representsNullType(InstanceKey key) {
|
||||
IClass cls = key.getConcreteType();
|
||||
Language L = cls.getClassLoader().getLanguage();
|
||||
return L.isNullType( cls.getReference() );
|
||||
}
|
||||
|
||||
/**
|
||||
* The FilterOperator is a filtered set-union. i.e. the LHS is `unioned' with
|
||||
* the RHS, but filtered by the set associated with this operator instance.
|
||||
|
@ -1308,16 +1309,18 @@ public abstract class PropagationCallGraphBuilder implements CallGraphBuilder {
|
|||
IntSetAction action = new IntSetAction() {
|
||||
public void act(int i) {
|
||||
InstanceKey I = system.getInstanceKey(i);
|
||||
PointerKey p = getPointerKeyForInstanceField(I, getField());
|
||||
if (! representsNullType(I)) {
|
||||
PointerKey p = getPointerKeyForInstanceField(I, getField());
|
||||
|
||||
if (p != null) {
|
||||
if (DEBUG_GET) {
|
||||
String S = "Getfield add constraint " + dVal + " " + p;
|
||||
Trace.guardedPrintln(S, DEBUG_METHOD_SUBSTRING);
|
||||
}
|
||||
sideEffect.b |= system.newFieldRead(dVal, assignOperator, p, object);
|
||||
}
|
||||
}
|
||||
if (p != null) {
|
||||
if (DEBUG_GET) {
|
||||
String S = "Getfield add constraint " + dVal + " " + p;
|
||||
Trace.guardedPrintln(S, DEBUG_METHOD_SUBSTRING);
|
||||
}
|
||||
sideEffect.b |= system.newFieldRead(dVal, assignOperator, p, object);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
if (priorInstances != null) {
|
||||
// temp for performance debugging
|
||||
|
@ -1436,17 +1439,19 @@ public abstract class PropagationCallGraphBuilder implements CallGraphBuilder {
|
|||
IntSetAction action = new IntSetAction() {
|
||||
public void act(int i) {
|
||||
InstanceKey I = system.getInstanceKey(i);
|
||||
if (DEBUG_PUT) {
|
||||
String S = "Putfield consider instance " + I;
|
||||
Trace.guardedPrintln(S, DEBUG_METHOD_SUBSTRING);
|
||||
}
|
||||
PointerKey p = getPointerKeyForInstanceField(I, getField());
|
||||
if (DEBUG_PUT) {
|
||||
String S = "Putfield add constraint " + p + " " + pVal;
|
||||
Trace.guardedPrintln(S, DEBUG_METHOD_SUBSTRING);
|
||||
}
|
||||
sideEffect.b |= system.newFieldWrite(p, assign, pVal, object);
|
||||
}
|
||||
if (! representsNullType(I)) {
|
||||
if (DEBUG_PUT) {
|
||||
String S = "Putfield consider instance " + I;
|
||||
Trace.guardedPrintln(S, DEBUG_METHOD_SUBSTRING);
|
||||
}
|
||||
PointerKey p = getPointerKeyForInstanceField(I, getField());
|
||||
if (DEBUG_PUT) {
|
||||
String S = "Putfield add constraint " + p + " " + pVal;
|
||||
Trace.guardedPrintln(S, DEBUG_METHOD_SUBSTRING);
|
||||
}
|
||||
sideEffect.b |= system.newFieldWrite(p, assign, pVal, object);
|
||||
}
|
||||
}
|
||||
};
|
||||
if (priorInstances != null) {
|
||||
value.foreachExcluding(priorInstances, action);
|
||||
|
@ -1538,9 +1543,11 @@ public abstract class PropagationCallGraphBuilder implements CallGraphBuilder {
|
|||
IntSetAction action = new IntSetAction() {
|
||||
public void act(int i) {
|
||||
InstanceKey I = system.getInstanceKey(i);
|
||||
PointerKey p = getPointerKeyForInstanceField(I, field);
|
||||
sideEffect.b |= system.newConstraint(p, instance);
|
||||
}
|
||||
if (! representsNullType(I)) {
|
||||
PointerKey p = getPointerKeyForInstanceField(I, field);
|
||||
sideEffect.b |= system.newConstraint(p, instance);
|
||||
}
|
||||
}
|
||||
};
|
||||
if (priorInstances != null) {
|
||||
value.foreachExcluding(priorInstances, action);
|
||||
|
|
|
@ -723,13 +723,15 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
system.recordImplicitPointsToSet(arrayRef);
|
||||
InstanceKey[] ik = getInvariantContents(instruction.getArrayRef());
|
||||
for (int i = 0; i < ik.length; i++) {
|
||||
system.findOrCreateIndexForInstanceKey(ik[i]);
|
||||
PointerKey p = getPointerKeyForArrayContents(ik[i]);
|
||||
if (p == null) {
|
||||
getWarnings().add(ResolutionFailure.create(node, ik[i].getConcreteType()));
|
||||
} else {
|
||||
system.newConstraint(result, assignOperator, p);
|
||||
}
|
||||
if (! representsNullType(ik[i])) {
|
||||
system.findOrCreateIndexForInstanceKey(ik[i]);
|
||||
PointerKey p = getPointerKeyForArrayContents(ik[i]);
|
||||
if (p == null) {
|
||||
getWarnings().add(ResolutionFailure.create(node, ik[i].getConcreteType()));
|
||||
} else {
|
||||
system.newConstraint(result, assignOperator, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Assertions.verifyAssertions) {
|
||||
|
@ -762,37 +764,39 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
InstanceKey[] ik = getInvariantContents(instruction.getArrayRef());
|
||||
|
||||
for (int i = 0; i < ik.length; i++) {
|
||||
system.findOrCreateIndexForInstanceKey(ik[i]);
|
||||
PointerKey p = getPointerKeyForArrayContents(ik[i]);
|
||||
IClass contents = ((ArrayClass) ik[i].getConcreteType()).getElementClass();
|
||||
if (p == null) {
|
||||
getWarnings().add(ResolutionFailure.create(node, ik[i].getConcreteType()));
|
||||
} else {
|
||||
if (DEBUG_TRACK_INSTANCE) {
|
||||
if (system.findOrCreateIndexForInstanceKey(ik[i]) == DEBUG_INSTANCE_KEY) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
}
|
||||
if (contentsAreInvariant(symbolTable, du, instruction.getValue())) {
|
||||
system.recordImplicitPointsToSet(value);
|
||||
InstanceKey[] vk = getInvariantContents(instruction.getValue());
|
||||
for (int j = 0; j < vk.length; j++) {
|
||||
system.findOrCreateIndexForInstanceKey(vk[j]);
|
||||
if (vk[j].getConcreteType() != null) {
|
||||
if (getClassHierarchy().isAssignableFrom(contents, vk[j].getConcreteType())) {
|
||||
system.newConstraint(p, vk[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isRootType(contents)) {
|
||||
system.newConstraint(p, assignOperator, value);
|
||||
} else {
|
||||
system.newConstraint(p, getBuilder().filterOperator, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (! representsNullType(ik[i])) {
|
||||
system.findOrCreateIndexForInstanceKey(ik[i]);
|
||||
PointerKey p = getPointerKeyForArrayContents(ik[i]);
|
||||
IClass contents = ((ArrayClass) ik[i].getConcreteType()).getElementClass();
|
||||
if (p == null) {
|
||||
getWarnings().add(ResolutionFailure.create(node, ik[i].getConcreteType()));
|
||||
} else {
|
||||
if (DEBUG_TRACK_INSTANCE) {
|
||||
if (system.findOrCreateIndexForInstanceKey(ik[i]) == DEBUG_INSTANCE_KEY) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
}
|
||||
if (contentsAreInvariant(symbolTable, du, instruction.getValue())) {
|
||||
system.recordImplicitPointsToSet(value);
|
||||
InstanceKey[] vk = getInvariantContents(instruction.getValue());
|
||||
for (int j = 0; j < vk.length; j++) {
|
||||
system.findOrCreateIndexForInstanceKey(vk[j]);
|
||||
if (vk[j].getConcreteType() != null) {
|
||||
if (getClassHierarchy().isAssignableFrom(contents, vk[j].getConcreteType())) {
|
||||
system.newConstraint(p, vk[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isRootType(contents)) {
|
||||
system.newConstraint(p, assignOperator, value);
|
||||
} else {
|
||||
system.newConstraint(p, getBuilder().filterOperator, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (contentsAreInvariant(symbolTable, du, instruction.getValue())) {
|
||||
system.recordImplicitPointsToSet(value);
|
||||
|
@ -951,10 +955,12 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
system.recordImplicitPointsToSet(refKey);
|
||||
InstanceKey[] ik = getInvariantContents(ref);
|
||||
for (int i = 0; i < ik.length; i++) {
|
||||
system.findOrCreateIndexForInstanceKey(ik[i]);
|
||||
PointerKey p = getPointerKeyForInstanceField(ik[i], f);
|
||||
system.newConstraint(def, assignOperator, p);
|
||||
}
|
||||
if (! representsNullType(ik[i])) {
|
||||
system.findOrCreateIndexForInstanceKey(ik[i]);
|
||||
PointerKey p = getPointerKeyForInstanceField(ik[i], f);
|
||||
system.newConstraint(def, assignOperator, p);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
system.newSideEffect(getBuilder().new GetFieldOperator(f, system.findOrCreatePointsToSet(def)), refKey);
|
||||
}
|
||||
|
@ -1013,12 +1019,14 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
system.recordImplicitPointsToSet(refKey);
|
||||
InstanceKey[] refk = getInvariantContents(ref);
|
||||
for (int j = 0; j < refk.length; j++) {
|
||||
system.findOrCreateIndexForInstanceKey(refk[j]);
|
||||
PointerKey p = getPointerKeyForInstanceField(refk[j], f);
|
||||
for (int i = 0; i < ik.length; i++) {
|
||||
system.newConstraint(p, ik[i]);
|
||||
}
|
||||
}
|
||||
if (! representsNullType(refk[j])) {
|
||||
system.findOrCreateIndexForInstanceKey(refk[j]);
|
||||
PointerKey p = getPointerKeyForInstanceField(refk[j], f);
|
||||
for (int i = 0; i < ik.length; i++) {
|
||||
system.newConstraint(p, ik[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < ik.length; i++) {
|
||||
system.findOrCreateIndexForInstanceKey(ik[i]);
|
||||
|
@ -1030,10 +1038,12 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
system.recordImplicitPointsToSet(refKey);
|
||||
InstanceKey[] refk = getInvariantContents(ref);
|
||||
for (int j = 0; j < refk.length; j++) {
|
||||
system.findOrCreateIndexForInstanceKey(refk[j]);
|
||||
PointerKey p = getPointerKeyForInstanceField(refk[j], f);
|
||||
system.newConstraint(p, assignOperator, rvalKey);
|
||||
}
|
||||
if (! representsNullType(refk[j])) {
|
||||
system.findOrCreateIndexForInstanceKey(refk[j]);
|
||||
PointerKey p = getPointerKeyForInstanceField(refk[j], f);
|
||||
system.newConstraint(p, assignOperator, rvalKey);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
Trace.guardedPrintln("adding side effect " + f, DEBUG_METHOD_SUBSTRING);
|
||||
|
|
|
@ -82,7 +82,7 @@ public abstract class SSAAbstractInvokeInstruction extends SSAInstruction implem
|
|||
public int getReceiver() {
|
||||
if (Assertions.verifyAssertions) {
|
||||
IInvokeInstruction.IDispatch code = site.getInvocationCode();
|
||||
Assertions._assert(code != IInvokeInstruction.Dispatch.STATIC);
|
||||
Assertions._assert(code!=IInvokeInstruction.Dispatch.STATIC, toString());
|
||||
}
|
||||
return getUse(0);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue