Fix for bug with pi nodes reported by Andreas Sewe
We weren't handling the case where the val of the pi instruction had an implicit points-to set.
This commit is contained in:
parent
eac23e97a9
commit
30686135da
|
@ -24,14 +24,17 @@ class PiNodeCallGraphTestCase {
|
||||||
|
|
||||||
static class This implements Whatever {
|
static class This implements Whatever {
|
||||||
|
|
||||||
|
@Override
|
||||||
public void unary1() {
|
public void unary1() {
|
||||||
unary2();
|
unary2();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void unary2() {
|
public void unary2() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void binary(Whatever arg) {
|
public void binary(Whatever arg) {
|
||||||
this.unary1();
|
this.unary1();
|
||||||
arg.unary2();
|
arg.unary2();
|
||||||
|
@ -41,14 +44,17 @@ class PiNodeCallGraphTestCase {
|
||||||
|
|
||||||
static class That implements Whatever {
|
static class That implements Whatever {
|
||||||
|
|
||||||
|
@Override
|
||||||
public void unary1() {
|
public void unary1() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void unary2() {
|
public void unary2() {
|
||||||
unary1();
|
unary1();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void binary(Whatever arg) {
|
public void binary(Whatever arg) {
|
||||||
this.unary1();
|
this.unary1();
|
||||||
arg.unary2();
|
arg.unary2();
|
||||||
|
@ -67,6 +73,14 @@ class PiNodeCallGraphTestCase {
|
||||||
x.binary(z);
|
x.binary(z);
|
||||||
else
|
else
|
||||||
y.binary(z);
|
y.binary(z);
|
||||||
|
localCast();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void localCast() {
|
||||||
|
Whatever y = new That();
|
||||||
|
if (y instanceof This) {
|
||||||
|
y.binary(y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.ibm.wala.classLoader.CallSiteReference;
|
import com.ibm.wala.classLoader.CallSiteReference;
|
||||||
|
@ -37,6 +38,7 @@ import com.ibm.wala.types.TypeName;
|
||||||
import com.ibm.wala.types.TypeReference;
|
import com.ibm.wala.types.TypeReference;
|
||||||
import com.ibm.wala.util.CancelException;
|
import com.ibm.wala.util.CancelException;
|
||||||
import com.ibm.wala.util.collections.HashSetFactory;
|
import com.ibm.wala.util.collections.HashSetFactory;
|
||||||
|
import com.ibm.wala.util.collections.Iterator2List;
|
||||||
import com.ibm.wala.util.strings.Atom;
|
import com.ibm.wala.util.strings.Atom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,7 +85,7 @@ public class PiNodeCallGraphTest extends WalaTestCase {
|
||||||
return CallGraphTestUtil.buildZeroCFA(options, new AnalysisCache(), cha, scope, false);
|
return CallGraphTestUtil.buildZeroCFA(options, new AnalysisCache(), cha, scope, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkCallAssertions(CallGraph cg, int desiredNumberOfTargets, int desiredNumberOfCalls) {
|
private void checkCallAssertions(CallGraph cg, int desiredNumberOfTargets, int desiredNumberOfCalls, int numLocalCastCallees) {
|
||||||
|
|
||||||
int numberOfCalls = 0;
|
int numberOfCalls = 0;
|
||||||
Set<CGNode> callerNodes = HashSetFactory.make();
|
Set<CGNode> callerNodes = HashSetFactory.make();
|
||||||
|
@ -93,7 +95,7 @@ public class PiNodeCallGraphTest extends WalaTestCase {
|
||||||
|
|
||||||
for (CGNode n : callerNodes) {
|
for (CGNode n : callerNodes) {
|
||||||
for (Iterator<CallSiteReference> sites = n.iterateCallSites(); sites.hasNext();) {
|
for (Iterator<CallSiteReference> sites = n.iterateCallSites(); sites.hasNext();) {
|
||||||
CallSiteReference csRef = (CallSiteReference) sites.next();
|
CallSiteReference csRef = sites.next();
|
||||||
if (csRef.getDeclaredTarget().equals(unary2Ref)) {
|
if (csRef.getDeclaredTarget().equals(unary2Ref)) {
|
||||||
numberOfCalls++;
|
numberOfCalls++;
|
||||||
assert cg.getNumberOfTargets(n, csRef) == desiredNumberOfTargets;
|
assert cg.getNumberOfTargets(n, csRef) == desiredNumberOfTargets;
|
||||||
|
@ -101,15 +103,20 @@ public class PiNodeCallGraphTest extends WalaTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
assert numberOfCalls == desiredNumberOfCalls;
|
assert numberOfCalls == desiredNumberOfCalls;
|
||||||
|
|
||||||
|
CGNode localCastNode = cg.getNodes(MethodReference.findOrCreate(TypeReference.findOrCreate(loader, TestConstants.PI_TEST_MAIN), "localCast", "()V")).iterator().next();
|
||||||
|
int actualLocalCastCallees = cg.getSuccNodeCount(localCastNode);
|
||||||
|
Assert.assertEquals(numLocalCastCallees, actualLocalCastCallees);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void testNoPiNodes() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
@Test public void testNoPiNodes() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||||
checkCallAssertions(doGraph(false), 2, 2);
|
checkCallAssertions(doGraph(false), 2, 2, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void testPiNodes() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
@Test public void testPiNodes() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||||
checkCallAssertions(doGraph(true), 1, 2);
|
checkCallAssertions(doGraph(true), 1, 2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1262,6 +1262,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
||||||
system.recordImplicitPointsToSet(dst);
|
system.recordImplicitPointsToSet(dst);
|
||||||
} else {
|
} else {
|
||||||
ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg = ir.getControlFlowGraph();
|
ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg = ir.getControlFlowGraph();
|
||||||
|
int val = instruction.getVal();
|
||||||
if (com.ibm.wala.cfg.Util.endsWithConditionalBranch(cfg, getBasicBlock()) && cfg.getSuccNodeCount(getBasicBlock()) == 2) {
|
if (com.ibm.wala.cfg.Util.endsWithConditionalBranch(cfg, getBasicBlock()) && cfg.getSuccNodeCount(getBasicBlock()) == 2) {
|
||||||
SSAConditionalBranchInstruction cond = (SSAConditionalBranchInstruction) com.ibm.wala.cfg.Util.getLastInstruction(cfg,
|
SSAConditionalBranchInstruction cond = (SSAConditionalBranchInstruction) com.ibm.wala.cfg.Util.getLastInstruction(cfg,
|
||||||
getBasicBlock());
|
getBasicBlock());
|
||||||
|
@ -1275,31 +1276,42 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
||||||
IClass cls = getClassHierarchy().lookupClass(type);
|
IClass cls = getClassHierarchy().lookupClass(type);
|
||||||
if (cls == null) {
|
if (cls == null) {
|
||||||
PointerKey dst = getPointerKeyForLocal(instruction.getDef());
|
PointerKey dst = getPointerKeyForLocal(instruction.getDef());
|
||||||
addPiAssignment(dst, instruction.getVal());
|
addPiAssignment(dst, val);
|
||||||
} else {
|
} else {
|
||||||
PointerKey dst = getFilteredPointerKeyForLocal(instruction.getDef(), new FilteredPointerKey.SingleClassFilter(cls));
|
PointerKey dst = getFilteredPointerKeyForLocal(instruction.getDef(), new FilteredPointerKey.SingleClassFilter(cls));
|
||||||
PointerKey src = getPointerKeyForLocal(instruction.getVal());
|
// if true, only allow objects assignable to cls. otherwise, only allow objects
|
||||||
if ((target == com.ibm.wala.cfg.Util.getTakenSuccessor(cfg, getBasicBlock()) && direction == 1)
|
// *not* assignable to cls
|
||||||
|| (target == com.ibm.wala.cfg.Util.getNotTakenSuccessor(cfg, getBasicBlock()) && direction == -1)) {
|
boolean useFilter = (target == com.ibm.wala.cfg.Util.getTakenSuccessor(cfg, getBasicBlock()) && direction == 1)
|
||||||
system.newConstraint(dst, getBuilder().filterOperator, src);
|
|| (target == com.ibm.wala.cfg.Util.getNotTakenSuccessor(cfg, getBasicBlock()) && direction == -1);
|
||||||
|
PointerKey src = getPointerKeyForLocal(val);
|
||||||
|
if (contentsAreInvariant(symbolTable, du, val)) {
|
||||||
|
system.recordImplicitPointsToSet(src);
|
||||||
|
InstanceKey[] ik = getInvariantContents(val);
|
||||||
|
for (int j = 0; j < ik.length; j++) {
|
||||||
|
boolean assignable = getClassHierarchy().isAssignableFrom(cls, ik[j].getConcreteType());
|
||||||
|
if ((assignable && useFilter) || (!assignable && !useFilter)) {
|
||||||
|
system.newConstraint(dst, ik[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
system.newConstraint(dst, getBuilder().inverseFilterOperator, src);
|
FilterOperator op = useFilter ? getBuilder().filterOperator : getBuilder().inverseFilterOperator;
|
||||||
|
system.newConstraint(dst, op, src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ((dir = nullConstantTest(cond, instruction.getVal())) != 0) {
|
} else if ((dir = nullConstantTest(cond, val)) != 0) {
|
||||||
if ((target == com.ibm.wala.cfg.Util.getTakenSuccessor(cfg, getBasicBlock()) && dir == -1)
|
if ((target == com.ibm.wala.cfg.Util.getTakenSuccessor(cfg, getBasicBlock()) && dir == -1)
|
||||||
|| (target == com.ibm.wala.cfg.Util.getNotTakenSuccessor(cfg, getBasicBlock()) && dir == 1)) {
|
|| (target == com.ibm.wala.cfg.Util.getNotTakenSuccessor(cfg, getBasicBlock()) && dir == 1)) {
|
||||||
PointerKey dst = getPointerKeyForLocal(instruction.getDef());
|
PointerKey dst = getPointerKeyForLocal(instruction.getDef());
|
||||||
addPiAssignment(dst, instruction.getVal());
|
addPiAssignment(dst, val);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PointerKey dst = getPointerKeyForLocal(instruction.getDef());
|
PointerKey dst = getPointerKeyForLocal(instruction.getDef());
|
||||||
addPiAssignment(dst, instruction.getVal());
|
addPiAssignment(dst, val);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PointerKey dst = getPointerKeyForLocal(instruction.getDef());
|
PointerKey dst = getPointerKeyForLocal(instruction.getDef());
|
||||||
addPiAssignment(dst, instruction.getVal());
|
addPiAssignment(dst, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue