restructure to allow CGNodes to dwell in more than one CallGraph. lift some functions up from CGNode to CallGraph
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@1422 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
d72e0a1752
commit
fd1a1d4cae
|
@ -65,7 +65,7 @@ public class EMFBridge {
|
|||
for (Iterator it2 = n.iterateSites(); it2.hasNext();) {
|
||||
CallSiteReference site = (CallSiteReference) it2.next();
|
||||
ECallSite eSite = makeCallSite(method, site);
|
||||
for (Iterator it3 = n.getPossibleTargets(site).iterator(); it3.hasNext();) {
|
||||
for (Iterator it3 = cg.getPossibleTargets(n,site).iterator(); it3.hasNext();) {
|
||||
CGNode target = (CGNode) it3.next();
|
||||
result.addEdge(eSite, makeJavaMethod(target.getMethod().getReference()));
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
package com.ibm.wala.ipa.callgraph;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
|
@ -44,40 +43,44 @@ public interface CGNode extends INodeWithNumber, ContextItem {
|
|||
*/
|
||||
public Context getContext();
|
||||
|
||||
/**
|
||||
* Return the set of CGNodes that represent possible targets
|
||||
* of a particular call site when invoked in this context.
|
||||
*/
|
||||
Set<CGNode> getPossibleTargets(CallSiteReference site);
|
||||
// /**
|
||||
// * Return the set of CGNodes that represent possible targets
|
||||
// * of a particular call site when invoked in this context.
|
||||
// */
|
||||
// Set<CGNode> getPossibleTargets(CallSiteReference site);
|
||||
|
||||
/**
|
||||
* @return Iterator of CallSiteReference
|
||||
*/
|
||||
Iterator<CallSiteReference> iterateSites();
|
||||
|
||||
// /**
|
||||
// * @param target
|
||||
// * @return iterator of CallSiteReference, the call sites in this node that might
|
||||
// * dispatch to the target node.
|
||||
// */
|
||||
// Iterator<CallSiteReference> getPossibleSites(CGNode target);
|
||||
//
|
||||
/**
|
||||
* @param target
|
||||
* @return iterator of CallSiteReference, the call sites in this node that might
|
||||
* dispatch to the target node.
|
||||
*/
|
||||
Iterator<CallSiteReference> getPossibleSites(CGNode target);
|
||||
|
||||
/**
|
||||
* This is for use only by call graph builders ... not by the general
|
||||
* public. Clients should not use this.
|
||||
*
|
||||
* Record that a particular call site might resolve to a call to a
|
||||
* particular target node. Returns true if this is a new target
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean addTarget(CallSiteReference site, CGNode target);
|
||||
|
||||
/**
|
||||
* @return the number of nodes that the call site current may resolve
|
||||
* to
|
||||
*/
|
||||
public int getNumberOfTargets(CallSiteReference site);
|
||||
// /**
|
||||
// * @return the number of nodes that the call site current may resolve
|
||||
// * to
|
||||
// */
|
||||
// public int getNumberOfTargets(CallSiteReference site);
|
||||
|
||||
/**
|
||||
* @return the call graph in which this node dwells
|
||||
*/
|
||||
public CallGraph getCallGraph();
|
||||
// /**
|
||||
// * @return the call graph in which this node dwells
|
||||
// */
|
||||
// public CallGraph getCallGraph();
|
||||
|
||||
/**
|
||||
* @return the "default" IR for this node used by the governing call graph
|
||||
|
|
|
@ -11,8 +11,10 @@
|
|||
package com.ibm.wala.ipa.callgraph;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
|
@ -21,15 +23,15 @@ import com.ibm.wala.util.graph.NumberedGraph;
|
|||
/**
|
||||
* Basic interface for a call graph, which is a graph of CGNode
|
||||
*
|
||||
*
|
||||
*
|
||||
* @author Stephen Fink
|
||||
*/
|
||||
public interface CallGraph extends NumberedGraph<CGNode> {
|
||||
|
||||
/**
|
||||
* Return the (fake) interprocedural {@link CGNode root node}
|
||||
* of the call graph.
|
||||
*
|
||||
* Return the (fake) interprocedural {@link CGNode root node} of the call
|
||||
* graph.
|
||||
*
|
||||
* @return the "fake" root node the call graph
|
||||
*/
|
||||
public CGNode getFakeRootNode();
|
||||
|
@ -40,29 +42,40 @@ public interface CallGraph extends NumberedGraph<CGNode> {
|
|||
public Collection<CGNode> getEntrypointNodes();
|
||||
|
||||
/**
|
||||
* If you want to get <em> all </em> the nodes corresponding to
|
||||
* a particular method, regardless of context, then use
|
||||
* {@link CGNode getNodes}
|
||||
* If you want to get <em> all </em> the nodes corresponding to a particular
|
||||
* method, regardless of context, then use {@link CGNode getNodes}
|
||||
*
|
||||
* @return the node corresponding a method in a context
|
||||
*/
|
||||
public CGNode getNode(IMethod method, Context C);
|
||||
|
||||
/**
|
||||
* @param m a method reference
|
||||
* @return the set of all nodes in the call graph that represent
|
||||
* this method.
|
||||
* @param m
|
||||
* a method reference
|
||||
* @return the set of all nodes in the call graph that represent this method.
|
||||
*/
|
||||
public Set<CGNode> getNodes(MethodReference m);
|
||||
|
||||
/**
|
||||
* Dump the callgraph to the specified file in dotty(1) format.
|
||||
*/
|
||||
public void dump(String filename);
|
||||
|
||||
/**
|
||||
* @return the governing class hierarchy for this call graph
|
||||
*/
|
||||
public IClassHierarchy getClassHierarchy();
|
||||
|
||||
/**
|
||||
* Return the set of CGNodes that represent possible targets of a particular
|
||||
* call site from a particular node
|
||||
*/
|
||||
public Set<CGNode> getPossibleTargets(CGNode node, CallSiteReference site);
|
||||
|
||||
/**
|
||||
* @return the number of nodes that the call site may dispatch to
|
||||
*/
|
||||
public int getNumberOfTargets(CGNode node, CallSiteReference site);
|
||||
|
||||
/**
|
||||
* @return iterator of CallSiteReference, the call sites in a node that might
|
||||
* dispatch to the target node.
|
||||
*/
|
||||
Iterator<CallSiteReference> getPossibleSites(CGNode src, CGNode target);
|
||||
|
||||
}
|
||||
|
|
|
@ -10,10 +10,6 @@
|
|||
*******************************************************************************/
|
||||
package com.ibm.wala.ipa.callgraph.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
@ -94,9 +90,7 @@ public abstract class BasicCallGraph extends AbstractNumberedGraph<CGNode> imple
|
|||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void init() {
|
||||
fakeRoot = makeFakeRootNode();
|
||||
Key k = new Key(fakeRoot.getMethod(), fakeRoot.getContext());
|
||||
|
@ -197,8 +191,6 @@ public abstract class BasicCallGraph extends AbstractNumberedGraph<CGNode> imple
|
|||
return method;
|
||||
}
|
||||
|
||||
public abstract Set<CGNode> getPossibleTargets(CallSiteReference site);
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#equals(Object)
|
||||
*/
|
||||
|
@ -236,7 +228,7 @@ public abstract class BasicCallGraph extends AbstractNumberedGraph<CGNode> imple
|
|||
if (n.getMethod() != null) {
|
||||
for (Iterator sites = n.iterateSites(); sites.hasNext();) {
|
||||
CallSiteReference site = (CallSiteReference) sites.next();
|
||||
Iterator targets = n.getPossibleTargets(site).iterator();
|
||||
Iterator targets = getPossibleTargets(n, site).iterator();
|
||||
if (targets.hasNext()) {
|
||||
result.append(" - " + site + "\n");
|
||||
}
|
||||
|
@ -250,38 +242,6 @@ public abstract class BasicCallGraph extends AbstractNumberedGraph<CGNode> imple
|
|||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump this callgraph to the specified file in dotty(1) format.
|
||||
* @throws IllegalArgumentException if filename is null
|
||||
*/
|
||||
public void dump(String filename) {
|
||||
if (filename == null) {
|
||||
throw new IllegalArgumentException("filename is null");
|
||||
}
|
||||
File file = new File(filename);
|
||||
try {
|
||||
PrintWriter out = new PrintWriter(new FileOutputStream(file));
|
||||
out.println("digraph callgraph {");
|
||||
for (Iterator it = iterator(); it.hasNext();) {
|
||||
CGNode n = (CGNode) it.next();
|
||||
for (Iterator it2 = getSuccNodes(n); it2.hasNext();) {
|
||||
CGNode m = (CGNode) it2.next();
|
||||
out.println(" \"" + prettyPrint(n) + "\" -> \"" + prettyPrint(m) + "\"");
|
||||
}
|
||||
}
|
||||
out.println("}");
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
private String prettyPrint(CGNode n) {
|
||||
String s = n.toString().replace(",", "\\n");
|
||||
return s.replace(" > Context: ", "\\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNodeAndEdges(CGNode N) {
|
||||
Assertions.UNREACHABLE();
|
||||
|
|
|
@ -146,8 +146,7 @@ public class ExplicitCallGraph extends BasicCallGraph implements BytecodeConstan
|
|||
super(method, C);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<CGNode> getPossibleTargets(CallSiteReference site) {
|
||||
protected Set<CGNode> getPossibleTargets(CallSiteReference site) {
|
||||
Object result = targets.get(site.getProgramCounter());
|
||||
|
||||
if (result == null) {
|
||||
|
@ -165,7 +164,7 @@ public class ExplicitCallGraph extends BasicCallGraph implements BytecodeConstan
|
|||
}
|
||||
}
|
||||
|
||||
public IntSet getPossibleTargetNumbers(CallSiteReference site) {
|
||||
protected IntSet getPossibleTargetNumbers(CallSiteReference site) {
|
||||
Object t = targets.get(site.getProgramCounter());
|
||||
|
||||
if (t == null) {
|
||||
|
@ -180,7 +179,7 @@ public class ExplicitCallGraph extends BasicCallGraph implements BytecodeConstan
|
|||
/*
|
||||
* @see com.ibm.wala.ipa.callgraph.CGNode#getPossibleSites(com.ibm.wala.ipa.callgraph.CGNode)
|
||||
*/
|
||||
public Iterator<CallSiteReference> getPossibleSites(final CGNode to) {
|
||||
protected Iterator<CallSiteReference> getPossibleSites(final CGNode to) {
|
||||
final int n = getCallGraph().getNumber(to);
|
||||
return new FilterIterator<CallSiteReference>(iterateSites(), new Filter() {
|
||||
public boolean accepts(Object o) {
|
||||
|
@ -189,6 +188,19 @@ public class ExplicitCallGraph extends BasicCallGraph implements BytecodeConstan
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
protected int getNumberOfTargets(CallSiteReference site) {
|
||||
Object result = targets.get(site.getProgramCounter());
|
||||
|
||||
if (result == null) {
|
||||
return 0;
|
||||
} else if (result instanceof CGNode) {
|
||||
return 1;
|
||||
} else {
|
||||
return ((IntSet) result).size();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addTarget(CallSiteReference site, CGNode tNode) {
|
||||
|
@ -229,20 +241,6 @@ public class ExplicitCallGraph extends BasicCallGraph implements BytecodeConstan
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.detox.ipa.callgraph.CGNode#getNumberOfTargets(com.ibm.wala.classLoader.CallSiteReference)
|
||||
*/
|
||||
public int getNumberOfTargets(CallSiteReference site) {
|
||||
Object result = targets.get(site.getProgramCounter());
|
||||
|
||||
if (result == null) {
|
||||
return 0;
|
||||
} else if (result instanceof CGNode) {
|
||||
return 1;
|
||||
} else {
|
||||
return ((IntSet) result).size();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.ipa.callgraph.CGNode#iterateSites()
|
||||
|
@ -295,7 +293,7 @@ public class ExplicitCallGraph extends BasicCallGraph implements BytecodeConstan
|
|||
return getMethod().hashCode() * 8681 + getContext().hashCode();
|
||||
}
|
||||
|
||||
public MutableSharedBitVectorIntSet getAllTargetNumbers() {
|
||||
protected MutableSharedBitVectorIntSet getAllTargetNumbers() {
|
||||
return allTargets;
|
||||
}
|
||||
|
||||
|
@ -441,4 +439,43 @@ public class ExplicitCallGraph extends BasicCallGraph implements BytecodeConstan
|
|||
protected ExplicitEdgeManager makeEdgeManger() {
|
||||
return new ExplicitEdgeManager();
|
||||
}
|
||||
|
||||
public int getNumberOfTargets(CGNode node, CallSiteReference site) {
|
||||
if (!containsNode(node)) {
|
||||
throw new IllegalArgumentException("node not in callgraph " + node);
|
||||
}
|
||||
assert (node instanceof ExplicitNode);
|
||||
ExplicitNode n = (ExplicitNode)node;
|
||||
return n.getNumberOfTargets(site);
|
||||
}
|
||||
|
||||
public Iterator<CallSiteReference> getPossibleSites(CGNode src, CGNode target) {
|
||||
if (!containsNode(src)) {
|
||||
throw new IllegalArgumentException("node not in callgraph " + src);
|
||||
}
|
||||
if (!containsNode(target)) {
|
||||
throw new IllegalArgumentException("node not in callgraph " + target);
|
||||
}
|
||||
assert (src instanceof ExplicitNode);
|
||||
ExplicitNode n = (ExplicitNode)src;
|
||||
return n.getPossibleSites(target);
|
||||
}
|
||||
|
||||
public Set<CGNode> getPossibleTargets(CGNode node, CallSiteReference site) {
|
||||
if (!containsNode(node)) {
|
||||
throw new IllegalArgumentException("node not in callgraph " + node);
|
||||
}
|
||||
assert (node instanceof ExplicitNode);
|
||||
ExplicitNode n = (ExplicitNode)node;
|
||||
return n.getPossibleTargets(site);
|
||||
}
|
||||
|
||||
public IntSet getPossibleTargetNumbers(CGNode node, CallSiteReference site) {
|
||||
if (!containsNode(node)) {
|
||||
throw new IllegalArgumentException("node not in callgraph " + node);
|
||||
}
|
||||
assert (node instanceof ExplicitNode);
|
||||
ExplicitNode n = (ExplicitNode)node;
|
||||
return n.getPossibleTargetNumbers(site);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Collection;
|
|||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
|
@ -125,4 +126,19 @@ public class PartialCallGraph extends DelegatingGraph<CGNode> implements CallGra
|
|||
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getNumberOfTargets(CGNode node, CallSiteReference site) {
|
||||
Assertions.UNREACHABLE("TODO");
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Iterator<CallSiteReference> getPossibleSites(CGNode src, CGNode target) {
|
||||
Assertions.UNREACHABLE("TODO");
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<CGNode> getPossibleTargets(CGNode node, CallSiteReference site) {
|
||||
Assertions.UNREACHABLE("TODO");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -424,14 +424,12 @@ public class PointerAnalysisImpl extends AbstractPointerAnalysis {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param call
|
||||
* @return the points-to set for the exceptional return values from a
|
||||
* particular call site
|
||||
*/
|
||||
private OrdinalSet<InstanceKey> computeImplicitExceptionsForCall(CGNode node, SSAInvokeInstruction call) {
|
||||
MutableSparseIntSet S = new MutableSparseIntSet();
|
||||
for (Iterator it = node.getPossibleTargets(call.getCallSite()).iterator(); it.hasNext();) {
|
||||
for (Iterator it = getCallGraph().getPossibleTargets(node, call.getCallSite()).iterator(); it.hasNext();) {
|
||||
CGNode target = (CGNode) it.next();
|
||||
PointerKey retVal = pointerKeys.getPointerKeyForExceptionalReturnValue(target);
|
||||
IntSet set = getPointsToSet(retVal).getBackingSet();
|
||||
|
|
|
@ -461,7 +461,7 @@ public class PointerFlowGraph extends AbstractGraph<PointerKey> {
|
|||
@Override
|
||||
public void visitInvoke(SSAInvokeInstruction instruction) {
|
||||
|
||||
for (Iterator it = node.getPossibleTargets(instruction.getCallSite()).iterator(); it.hasNext();) {
|
||||
for (Iterator it = cg.getPossibleTargets(node, instruction.getCallSite()).iterator(); it.hasNext();) {
|
||||
CGNode target = (CGNode) it.next();
|
||||
|
||||
// some methods, like unmodelled natives, do not have IR.
|
||||
|
|
|
@ -1418,6 +1418,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
* if non-null, then this is the unique PointerKey that catches all
|
||||
* exceptions from this call site.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private void processResolvedCall(CGNode caller, SSAAbstractInvokeInstruction instruction, CGNode target,
|
||||
InstanceKey[][] constParams, PointerKey uniqueCatchKey) {
|
||||
|
||||
|
@ -1660,7 +1661,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
Trace.println("Warning: null target for call " + call + " " + iKey);
|
||||
}
|
||||
} else {
|
||||
IntSet targets = node.getPossibleTargetNumbers(call.getCallSite());
|
||||
IntSet targets = getCallGraph().getPossibleTargetNumbers(node,call.getCallSite());
|
||||
if (targets != null && targets.contains(target.getGraphNodeId())) {
|
||||
// do nothing; we've previously discovered and handled this
|
||||
// receiver for this call site.
|
||||
|
@ -1703,7 +1704,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
private boolean willNeverChangeAgain(IntSet receivers) {
|
||||
int bound = getBoundOnNumberOfTargets(node, call.getSite());
|
||||
if (bound > -1) {
|
||||
int nTargets = node.getNumberOfTargets(call.getSite());
|
||||
int nTargets = getCallGraph().getNumberOfTargets(node, call.getSite());
|
||||
if (Assertions.verifyAssertions) {
|
||||
if (nTargets > bound) {
|
||||
Trace.println("node: " + node);
|
||||
|
@ -1711,7 +1712,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
Trace.println("instruction " + call);
|
||||
Trace.println("nTargets: " + nTargets);
|
||||
Trace.println("bound: " + bound);
|
||||
for (Iterator it = node.getPossibleTargets(call.getSite()).iterator(); it.hasNext();) {
|
||||
for (Iterator it = getCallGraph().getPossibleTargets(node, call.getSite()).iterator(); it.hasNext();) {
|
||||
Trace.println(" " + it.next());
|
||||
}
|
||||
for (IntIterator intIt = receivers.intIterator(); intIt.hasNext();) {
|
||||
|
|
|
@ -323,6 +323,7 @@ public abstract class AbstractRTABuilder extends PropagationCallGraphBuilder {
|
|||
*
|
||||
* Side effect: add edge to the call graph.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
void processResolvedCall(CGNode caller, CallSiteReference site, CGNode target) {
|
||||
|
||||
if (DEBUG) {
|
||||
|
|
|
@ -188,7 +188,7 @@ public class BasicRTABuilder extends AbstractRTABuilder {
|
|||
}
|
||||
}
|
||||
|
||||
IntSet targets = caller.getPossibleTargetNumbers(site);
|
||||
IntSet targets = getCallGraph().getPossibleTargetNumbers(caller,site);
|
||||
if (targets != null && targets.contains(target.getGraphNodeId())) {
|
||||
// do nothing; we've previously discovered and handled this
|
||||
// receiver for this call site.
|
||||
|
|
|
@ -79,7 +79,7 @@ public class DelegatingExplicitCallGraph extends ExplicitCallGraph {
|
|||
Object n = it.next();
|
||||
if (n instanceof CallSite) {
|
||||
ExplicitNode delegate = (ExplicitNode) ((CallSite) n).getNode();
|
||||
IntSet s = delegate.getPossibleTargetNumbers(((CallSite) n).getSite());
|
||||
IntSet s = DelegatingExplicitCallGraph.this.getPossibleTargetNumbers(delegate, ((CallSite) n).getSite());
|
||||
if (s != null) {
|
||||
result.addAll(s);
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ public class DelegatingExplicitCallGraph extends ExplicitCallGraph {
|
|||
CallSite p = (CallSite) result;
|
||||
CGNode n = p.getNode();
|
||||
CallSiteReference s = p.getSite();
|
||||
return n.getPossibleTargets(s);
|
||||
return DelegatingExplicitCallGraph.this.getPossibleTargets(n, s);
|
||||
} else {
|
||||
return super.getPossibleTargets(site);
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ public class DelegatingExplicitCallGraph extends ExplicitCallGraph {
|
|||
Object n = it.next();
|
||||
if (n instanceof CallSite) {
|
||||
ExplicitNode delegate = (ExplicitNode) ((CallSite) n).getNode();
|
||||
IntSet s = delegate.getPossibleTargetNumbers(((CallSite) n).getSite());
|
||||
IntSet s = DelegatingExplicitCallGraph.this.getPossibleTargetNumbers(delegate,((CallSite) n).getSite());
|
||||
if (s!= null && s.contains(y)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ public class DelegatingExplicitCallGraph extends ExplicitCallGraph {
|
|||
CallSite p = (CallSite) result;
|
||||
CGNode n = p.getNode();
|
||||
CallSiteReference s = p.getSite();
|
||||
return n.getNumberOfTargets(s);
|
||||
return DelegatingExplicitCallGraph.this.getNumberOfTargets(n,s);
|
||||
} else {
|
||||
return super.getNumberOfTargets(site);
|
||||
}
|
||||
|
|
|
@ -277,7 +277,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
|
|||
Trace.println("got Site: " + site);
|
||||
}
|
||||
boolean irrelevantTargets = false;
|
||||
for (Iterator ts = n.getPossibleTargets(site).iterator(); ts.hasNext();) {
|
||||
for (Iterator ts = cg.getPossibleTargets(n, site).iterator(); ts.hasNext();) {
|
||||
CGNode tn = (CGNode) ts.next();
|
||||
if (!relevant.accepts(tn)) {
|
||||
if (DEBUG_LEVEL > 0) {
|
||||
|
@ -490,7 +490,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
|
|||
IInvokeInstruction call = (IInvokeInstruction) cinsts[i];
|
||||
CallSiteReference site = makeCallSiteReference(n.getMethod().getDeclaringClass().getClassLoader().getReference(), ccfg
|
||||
.getProgramCounter(i), call);
|
||||
if (caller.getPossibleTargets(site).contains(n)) {
|
||||
if (cg.getPossibleTargets(caller, site).contains(n)) {
|
||||
if (DEBUG_LEVEL > 0) {
|
||||
Trace.println("Adding edge " + ccfg.getBlockForInstruction(i) + " to " + bb);
|
||||
}
|
||||
|
@ -701,7 +701,6 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param B
|
||||
* @return the set of CGNodes that B may call, according to the governing call
|
||||
* graph.
|
||||
*/
|
||||
|
@ -710,8 +709,8 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
|
|||
IInvokeInstruction call = (IInvokeInstruction) statements[B.getLastInstructionIndex()];
|
||||
int pc = cfg.getProgramCounter(B.getLastInstructionIndex());
|
||||
CallSiteReference site = makeCallSiteReference(B.getMethod().getDeclaringClass().getClassLoader().getReference(), pc, call);
|
||||
HashSet<CGNode> result = HashSetFactory.make(Bnode.getNumberOfTargets(site));
|
||||
for (Iterator<CGNode> it = Bnode.getPossibleTargets(site).iterator(); it.hasNext();) {
|
||||
HashSet<CGNode> result = HashSetFactory.make(cg.getNumberOfTargets(Bnode,site));
|
||||
for (Iterator<CGNode> it = cg.getPossibleTargets(Bnode,site).iterator(); it.hasNext();) {
|
||||
CGNode target = it.next();
|
||||
result.add(target);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import com.ibm.wala.dataflow.graph.ITransferFunctionProvider;
|
|||
import com.ibm.wala.fixedpoint.impl.UnaryOperator;
|
||||
import com.ibm.wala.fixpoint.BitVectorVariable;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.StaticFieldKey;
|
||||
|
@ -93,7 +94,7 @@ public class HeapReachingDefs {
|
|||
* if statements is null
|
||||
*/
|
||||
public static Map<Statement, OrdinalSet<Statement>> computeReachingDefs(CGNode node, IR ir, PointerAnalysis pa,
|
||||
Map<CGNode, OrdinalSet<PointerKey>> mod, Collection<Statement> statements, HeapExclusions exclusions) {
|
||||
Map<CGNode, OrdinalSet<PointerKey>> mod, Collection<Statement> statements, HeapExclusions exclusions, CallGraph cg) {
|
||||
|
||||
if (statements == null) {
|
||||
throw new IllegalArgumentException("statements is null");
|
||||
|
@ -129,21 +130,24 @@ public class HeapReachingDefs {
|
|||
System.err.println("Solved. ");
|
||||
}
|
||||
return makeResult(solver, domain, node, new DelegatingExtendedHeapModel(pa.getHeapModel()), pa, mod, cfg,
|
||||
ssaInstructionIndex2Statement, exclusions);
|
||||
ssaInstructionIndex2Statement, exclusions, cg);
|
||||
}
|
||||
|
||||
private static class RDMap implements Map<Statement, OrdinalSet<Statement>> {
|
||||
final Map<Statement, OrdinalSet<Statement>> delegate = HashMapFactory.make();
|
||||
|
||||
private final HeapExclusions exclusions;
|
||||
|
||||
private final CallGraph cg;
|
||||
|
||||
RDMap(BitVectorSolver<IBasicBlock> solver, OrdinalSetMapping<Statement> domain, CGNode node, ExtendedHeapModel h,
|
||||
PointerAnalysis pa, Map<CGNode, OrdinalSet<PointerKey>> mod, ExpandedControlFlowGraph cfg,
|
||||
Map<Integer, NormalStatement> ssaInstructionIndex2Statement, HeapExclusions exclusions) {
|
||||
Map<Integer, NormalStatement> ssaInstructionIndex2Statement, HeapExclusions exclusions, CallGraph cg) {
|
||||
if (VERBOSE) {
|
||||
System.err.println("Init pointer Key mod ");
|
||||
}
|
||||
this.exclusions = exclusions;
|
||||
this.cg = cg;
|
||||
Map<PointerKey, MutableIntSet> pointerKeyMod = initPointerKeyMod(domain, node, h, pa);
|
||||
if (VERBOSE) {
|
||||
System.err.println("Eager populate");
|
||||
|
@ -313,7 +317,7 @@ public class HeapReachingDefs {
|
|||
HeapStatement.ReturnCaller r = (HeapStatement.ReturnCaller) s;
|
||||
IBasicBlock bb = cfg.getBlockForInstruction(r.getCall());
|
||||
BitVectorVariable v = (BitVectorVariable) solver.getIn(bb);
|
||||
if (allCalleesMod(r, mod) || pointerKeyMod.get(r.getLocation()) == null || v.getValue() == null) {
|
||||
if (allCalleesMod(cg, r, mod) || pointerKeyMod.get(r.getLocation()) == null || v.getValue() == null) {
|
||||
// do nothing ... force flow into and out of the callees
|
||||
return OrdinalSet.empty();
|
||||
} else {
|
||||
|
@ -364,19 +368,17 @@ public class HeapReachingDefs {
|
|||
private static Map<Statement, OrdinalSet<Statement>> makeResult(BitVectorSolver<IBasicBlock> solver,
|
||||
OrdinalSetMapping<Statement> domain, CGNode node, ExtendedHeapModel h, PointerAnalysis pa,
|
||||
Map<CGNode, OrdinalSet<PointerKey>> mod, ExpandedControlFlowGraph cfg,
|
||||
Map<Integer, NormalStatement> ssaInstructionIndex2Statement, HeapExclusions exclusions) {
|
||||
Map<Integer, NormalStatement> ssaInstructionIndex2Statement, HeapExclusions exclusions, CallGraph cg) {
|
||||
|
||||
return new RDMap(solver, domain, node, h, pa, mod, cfg, ssaInstructionIndex2Statement, exclusions);
|
||||
return new RDMap(solver, domain, node, h, pa, mod, cfg, ssaInstructionIndex2Statement, exclusions, cg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do all callees corresponding to the given call site def the pointer key
|
||||
* being tracked by r?
|
||||
*
|
||||
* @param mod
|
||||
*/
|
||||
private static boolean allCalleesMod(ReturnCaller r, Map<CGNode, OrdinalSet<PointerKey>> mod) {
|
||||
Collection<CGNode> targets = r.getNode().getPossibleTargets(r.getCall().getCallSite());
|
||||
private static boolean allCalleesMod(CallGraph cg, ReturnCaller r, Map<CGNode, OrdinalSet<PointerKey>> mod) {
|
||||
Collection<CGNode> targets = cg.getPossibleTargets(r.getNode(), r.getCall().getCallSite());
|
||||
if (targets.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import com.ibm.wala.cfg.cdg.ControlDependenceGraph;
|
|||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
|
@ -96,6 +97,8 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
private final Map<CGNode, OrdinalSet<PointerKey>> mod;
|
||||
|
||||
private final DataDependenceOptions dOptions;
|
||||
|
||||
private final CallGraph cg;
|
||||
|
||||
/**
|
||||
* @param mod
|
||||
|
@ -109,12 +112,13 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
*/
|
||||
public PDG(final CGNode node, PointerAnalysis pa, Map<CGNode, OrdinalSet<PointerKey>> mod,
|
||||
Map<CGNode, OrdinalSet<PointerKey>> ref, DataDependenceOptions dOptions, ControlDependenceOptions cOptions,
|
||||
HeapExclusions exclusions) {
|
||||
HeapExclusions exclusions, CallGraph cg) {
|
||||
|
||||
super();
|
||||
if (node == null) {
|
||||
throw new IllegalArgumentException("node is null");
|
||||
}
|
||||
this.cg = cg;
|
||||
this.node = node;
|
||||
this.heapModel = pa == null ? null : new DelegatingExtendedHeapModel(pa.getHeapModel());
|
||||
this.pa = pa;
|
||||
|
@ -493,7 +497,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
Collection<Statement> relevantStatements = Iterator2Collection.toCollection(new FilterIterator<Statement>(iterator(), f));
|
||||
|
||||
Map<Statement, OrdinalSet<Statement>> heapReachingDefs = dOptions.isIgnoreHeap() ? null : HeapReachingDefs.computeReachingDefs(
|
||||
node, ir, pa, mod, relevantStatements, new HeapExclusions(SetComplement.complement(new SingletonSet(t))));
|
||||
node, ir, pa, mod, relevantStatements, new HeapExclusions(SetComplement.complement(new SingletonSet(t))), cg);
|
||||
|
||||
for (Statement st : heapReachingDefs.keySet()) {
|
||||
switch (st.getKind()) {
|
||||
|
@ -829,13 +833,13 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
}
|
||||
|
||||
if (!dOptions.isIgnoreHeap()) {
|
||||
OrdinalSet<PointerKey> uref = unionHeapLocations(node, call, ref);
|
||||
OrdinalSet<PointerKey> uref = unionHeapLocations(cg, node, call, ref);
|
||||
for (PointerKey p : uref) {
|
||||
Statement st = new HeapStatement.ParamCaller(node, callIndex, p);
|
||||
addNode(st);
|
||||
params.add(st);
|
||||
}
|
||||
OrdinalSet<PointerKey> umod = unionHeapLocations(node, call, mod);
|
||||
OrdinalSet<PointerKey> umod = unionHeapLocations(cg, node, call, mod);
|
||||
for (PointerKey p : umod) {
|
||||
Statement st = new HeapStatement.ReturnCaller(node, callIndex, p);
|
||||
addNode(st);
|
||||
|
@ -847,10 +851,10 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
/**
|
||||
* @return the set of all locations read by any callee at a call site.
|
||||
*/
|
||||
private OrdinalSet<PointerKey> unionHeapLocations(CGNode n, SSAAbstractInvokeInstruction call,
|
||||
private OrdinalSet<PointerKey> unionHeapLocations(CallGraph cg, CGNode n, SSAAbstractInvokeInstruction call,
|
||||
Map<CGNode, OrdinalSet<PointerKey>> loc) {
|
||||
BitVectorIntSet bv = new BitVectorIntSet();
|
||||
for (CGNode t : n.getPossibleTargets(call.getCallSite())) {
|
||||
for (CGNode t : cg.getPossibleTargets(n, call.getCallSite())) {
|
||||
bv.addAll(loc.get(t).getBackingSet());
|
||||
}
|
||||
return new OrdinalSet<PointerKey>(bv, loc.get(n).getMapping());
|
||||
|
|
|
@ -212,7 +212,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
Collection<Statement> result = Iterator2Collection.toCollection(getPDG(N.getNode()).getPredNodes(N));
|
||||
if (!dOptions.equals(DataDependenceOptions.NONE)) {
|
||||
// data dependence predecessors
|
||||
for (CGNode t : N.getNode().getPossibleTargets(call.getCallSite())) {
|
||||
for (CGNode t : cg.getPossibleTargets(N.getNode(),call.getCallSite())) {
|
||||
Statement s = new ParamStatement.ExceptionalReturnCallee(t);
|
||||
addNode(s);
|
||||
result.add(s);
|
||||
|
@ -226,7 +226,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
Collection<Statement> result = Iterator2Collection.toCollection(getPDG(N.getNode()).getPredNodes(N));
|
||||
if (!dOptions.equals(DataDependenceOptions.NONE)) {
|
||||
// data dependence predecessors
|
||||
for (CGNode t : N.getNode().getPossibleTargets(call.getCallSite())) {
|
||||
for (CGNode t : cg.getPossibleTargets(N.getNode(), call.getCallSite())) {
|
||||
Statement s = new ParamStatement.NormalReturnCallee(t);
|
||||
addNode(s);
|
||||
result.add(s);
|
||||
|
@ -240,7 +240,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
Collection<Statement> result = Iterator2Collection.toCollection(getPDG(N.getNode()).getPredNodes(N));
|
||||
if (!dOptions.equals(DataDependenceOptions.NONE)) {
|
||||
// data dependence predecessors
|
||||
for (CGNode t : N.getNode().getPossibleTargets(call.getCallSite())) {
|
||||
for (CGNode t : cg.getPossibleTargets(N.getNode(), call.getCallSite())) {
|
||||
if (mod.get(t).contains(r.getLocation())) {
|
||||
Statement s = new HeapStatement.ReturnCallee(t, r.getLocation());
|
||||
addNode(s);
|
||||
|
@ -258,7 +258,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
// data dependence predecessors
|
||||
for (Iterator<? extends CGNode> it = cg.getPredNodes(N.getNode()); it.hasNext();) {
|
||||
CGNode caller = it.next();
|
||||
for (Iterator<CallSiteReference> it2 = caller.getPossibleSites(N.getNode()); it2.hasNext();) {
|
||||
for (Iterator<CallSiteReference> it2 = cg.getPossibleSites(caller, N.getNode()); it2.hasNext();) {
|
||||
CallSiteReference site = it2.next();
|
||||
IR ir = caller.getIR();
|
||||
IntSet indices = ir.getCallInstructionIndices(site);
|
||||
|
@ -287,7 +287,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
// data dependence predecessors
|
||||
for (Iterator<? extends CGNode> it = cg.getPredNodes(N.getNode()); it.hasNext();) {
|
||||
CGNode caller = it.next();
|
||||
for (Iterator<CallSiteReference> it2 = caller.getPossibleSites(N.getNode()); it2.hasNext();) {
|
||||
for (Iterator<CallSiteReference> it2 = cg.getPossibleSites(caller, N.getNode()); it2.hasNext();) {
|
||||
CallSiteReference site = it2.next();
|
||||
IR ir = caller.getIR();
|
||||
IntSet indices = ir.getCallInstructionIndices(site);
|
||||
|
@ -312,7 +312,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
if (!cOptions.equals(ControlDependenceOptions.NONE)) {
|
||||
for (Iterator<? extends CGNode> it = cg.getPredNodes(N.getNode()); it.hasNext();) {
|
||||
CGNode caller = it.next();
|
||||
for (Iterator<CallSiteReference> it2 = caller.getPossibleSites(N.getNode()); it2.hasNext();) {
|
||||
for (Iterator<CallSiteReference> it2 = cg.getPossibleSites(caller, N.getNode()); it2.hasNext();) {
|
||||
CallSiteReference site = it2.next();
|
||||
IR ir = caller.getIR();
|
||||
IntSet indices = ir.getCallInstructionIndices(site);
|
||||
|
@ -346,7 +346,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
if (ns.getInstruction() instanceof SSAAbstractInvokeInstruction) {
|
||||
HashSet<Statement> result = HashSetFactory.make();
|
||||
SSAAbstractInvokeInstruction call = (SSAAbstractInvokeInstruction) ns.getInstruction();
|
||||
for (CGNode t : N.getNode().getPossibleTargets(call.getCallSite())) {
|
||||
for (CGNode t : cg.getPossibleTargets(N.getNode(), call.getCallSite())) {
|
||||
Statement s = new MethodEntryStatement(t);
|
||||
addNode(s);
|
||||
result.add(s);
|
||||
|
@ -371,7 +371,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
// data dependence predecessors
|
||||
for (Iterator<? extends CGNode> it = cg.getPredNodes(N.getNode()); it.hasNext();) {
|
||||
CGNode caller = it.next();
|
||||
for (Iterator<CallSiteReference> it2 = caller.getPossibleSites(N.getNode()); it2.hasNext();) {
|
||||
for (Iterator<CallSiteReference> it2 = cg.getPossibleSites(caller, N.getNode()); it2.hasNext();) {
|
||||
CallSiteReference site = it2.next();
|
||||
IR ir = caller.getIR();
|
||||
IntSet indices = ir.getCallInstructionIndices(site);
|
||||
|
@ -393,7 +393,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
// data dependence predecessors
|
||||
for (Iterator<? extends CGNode> it = cg.getPredNodes(N.getNode()); it.hasNext();) {
|
||||
CGNode caller = it.next();
|
||||
for (Iterator<CallSiteReference> it2 = caller.getPossibleSites(N.getNode()); it2.hasNext();) {
|
||||
for (Iterator<CallSiteReference> it2 = cg.getPossibleSites(caller, N.getNode()); it2.hasNext();) {
|
||||
CallSiteReference site = it2.next();
|
||||
IR ir = caller.getIR();
|
||||
IntSet indices = ir.getCallInstructionIndices(site);
|
||||
|
@ -416,7 +416,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
// data dependence predecessors
|
||||
for (Iterator<? extends CGNode> it = cg.getPredNodes(N.getNode()); it.hasNext();) {
|
||||
CGNode caller = it.next();
|
||||
for (Iterator<CallSiteReference> it2 = caller.getPossibleSites(N.getNode()); it2.hasNext();) {
|
||||
for (Iterator<CallSiteReference> it2 = cg.getPossibleSites(caller, N.getNode()); it2.hasNext();) {
|
||||
CallSiteReference site = it2.next();
|
||||
IR ir = caller.getIR();
|
||||
IntSet indices = ir.getCallInstructionIndices(site);
|
||||
|
@ -437,7 +437,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
Collection<Statement> result = HashSetFactory.make(5);
|
||||
if (!dOptions.equals(DataDependenceOptions.NONE)) {
|
||||
// data dependence successors
|
||||
for (CGNode t : N.getNode().getPossibleTargets(call.getCallSite())) {
|
||||
for (CGNode t : cg.getPossibleTargets(N.getNode(), call.getCallSite())) {
|
||||
for (int i = 0; i < t.getMethod().getNumberOfParameters(); i++) {
|
||||
if (call.getUse(i) == pac.getValueNumber()) {
|
||||
Statement s = new ParamStatement.ParamCallee(t, i + 1);
|
||||
|
@ -455,7 +455,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
Collection<Statement> result = HashSetFactory.make(5);
|
||||
if (!dOptions.equals(DataDependenceOptions.NONE)) {
|
||||
// data dependence successors
|
||||
for (CGNode t : N.getNode().getPossibleTargets(call.getCallSite())) {
|
||||
for (CGNode t : cg.getPossibleTargets(N.getNode(), call.getCallSite())) {
|
||||
if (ref.get(t).contains(pc.getLocation())) {
|
||||
Statement s = new HeapStatement.ParamCallee(t, pc.getLocation());
|
||||
addNode(s);
|
||||
|
@ -480,7 +480,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
if (dst instanceof MethodEntryStatement) {
|
||||
if (ns.getInstruction() instanceof SSAAbstractInvokeInstruction) {
|
||||
SSAAbstractInvokeInstruction call = (SSAAbstractInvokeInstruction) ns.getInstruction();
|
||||
return src.getNode().getPossibleTargets(call.getCallSite()).contains(dst.getNode());
|
||||
return cg.getPossibleTargets(src.getNode(), call.getCallSite()).contains(dst.getNode());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -502,7 +502,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
}
|
||||
if (dst.getKind().equals(Kind.EXC_RET_CALLER)) {
|
||||
ParamStatement.ExceptionalReturnCaller r = (ParamStatement.ExceptionalReturnCaller) dst;
|
||||
return r.getNode().getPossibleTargets(r.getCall().getCallSite()).contains(src.getNode());
|
||||
return cg.getPossibleTargets(r.getNode(), r.getCall().getCallSite()).contains(src.getNode());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -513,7 +513,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
}
|
||||
if (dst.getKind().equals(Kind.NORMAL_RET_CALLER)) {
|
||||
ParamStatement.NormalReturnCaller r = (ParamStatement.NormalReturnCaller) dst;
|
||||
return r.getNode().getPossibleTargets(r.getCall().getCallSite()).contains(src.getNode());
|
||||
return cg.getPossibleTargets(r.getNode(), r.getCall().getCallSite()).contains(src.getNode());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -526,7 +526,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
HeapStatement.ReturnCaller r = (HeapStatement.ReturnCaller) dst;
|
||||
HeapStatement h = (HeapStatement) src;
|
||||
return h.getLocation().equals(r.getLocation())
|
||||
&& r.getNode().getPossibleTargets(r.getCall().getCallSite()).contains(src.getNode());
|
||||
&& cg.getPossibleTargets(r.getNode(), r.getCall().getCallSite()).contains(src.getNode());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -540,7 +540,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
ParamStatement.ParamCaller caller = (ParamStatement.ParamCaller) src;
|
||||
|
||||
return caller.getValueNumber() == callee.getValueNumber()
|
||||
&& caller.getNode().getPossibleTargets(caller.getCall().getCallSite()).contains(callee.getNode());
|
||||
&& cg.getPossibleTargets(caller.getNode(), caller.getCall().getCallSite()).contains(callee.getNode());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -554,7 +554,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
HeapStatement.ParamCaller caller = (HeapStatement.ParamCaller) src;
|
||||
|
||||
return caller.getLocation().equals(callee.getLocation())
|
||||
&& caller.getNode().getPossibleTargets(caller.getCall().getCallSite()).contains(callee.getNode());
|
||||
&& cg.getPossibleTargets(caller.getNode(), caller.getCall().getCallSite()).contains(callee.getNode());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -618,7 +618,7 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
public PDG getPDG(CGNode node) {
|
||||
PDG result = pdgMap.get(node);
|
||||
if (result == null) {
|
||||
result = new PDG(node, pa, mod, ref, dOptions, cOptions, heapExclude);
|
||||
result = new PDG(node, pa, mod, ref, dOptions, cOptions, heapExclude, cg);
|
||||
pdgMap.put(node, result);
|
||||
for (Iterator<? extends Statement> it = result.iterator(); it.hasNext();) {
|
||||
nodeMgr.addNode(it.next());
|
||||
|
@ -631,4 +631,8 @@ public class SDG extends AbstractNumberedGraph<Statement> implements ISDG {
|
|||
return cOptions;
|
||||
}
|
||||
|
||||
public CallGraph getCallGraph() {
|
||||
return cg;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue