Skip to content

Commit 6fdafcd

Browse files
authored
Merge pull request #2140 from MarcMil/mdev
JimpleBasedInterproceduralCFG: Allows to set a CHA-style fallback mode
2 parents 8d201bb + e640d7b commit 6fdafcd

File tree

1 file changed

+38
-11
lines changed

1 file changed

+38
-11
lines changed

src/main/java/soot/jimple/toolkits/ide/icfg/JimpleBasedInterproceduralCFG.java

+38-11
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import com.google.common.cache.LoadingCache;
2727

2828
import heros.DontSynchronize;
29-
import heros.InterproceduralCFG;
3029
import heros.SynchronizedBy;
3130
import heros.ThreadSafe;
3231
import heros.solver.IDESolver;
@@ -39,10 +38,15 @@
3938
import org.slf4j.Logger;
4039
import org.slf4j.LoggerFactory;
4140

41+
import soot.FastHierarchy;
4242
import soot.MethodOrMethodContext;
43+
import soot.RefType;
4344
import soot.Scene;
4445
import soot.SootMethod;
46+
import soot.Type;
4547
import soot.Unit;
48+
import soot.jimple.InstanceInvokeExpr;
49+
import soot.jimple.InvokeExpr;
4650
import soot.jimple.Stmt;
4751
import soot.jimple.toolkits.callgraph.CallGraph;
4852
import soot.jimple.toolkits.callgraph.Edge;
@@ -62,7 +66,23 @@ public class JimpleBasedInterproceduralCFG extends AbstractJimpleBasedICFG {
6266

6367
protected boolean includeReflectiveCalls = false;
6468
protected boolean includePhantomCallees = false;
65-
protected boolean fallbackToImmediateCallees = true;
69+
70+
public enum Fallback {
71+
/**
72+
* Do utilize any callee.
73+
*/
74+
NONE,
75+
/**
76+
* Use the immediate callee if the callgraph does not contain any edges for the respective call site.
77+
*/
78+
IMMEDIATE_CALLEES,
79+
/**
80+
* Assume Class-Hierarchy Analysis style that all subclasses are possible.
81+
*/
82+
CHA
83+
}
84+
85+
protected Fallback fallback = Fallback.NONE;
6686

6787
// retains only callers that are explicit call sites or Thread.start()
6888
public class EdgeFilter extends Filter {
@@ -108,10 +128,20 @@ public Collection<SootMethod> load(Unit u) throws Exception {
108128
res.trimToSize();
109129
return res;
110130
} else {
111-
if (fallbackToImmediateCallees && u instanceof Stmt) {
131+
if (fallback != Fallback.NONE && u instanceof Stmt) {
112132
Stmt s = (Stmt) u;
113133
if (s.containsInvokeExpr()) {
114-
SootMethod immediate = s.getInvokeExpr().getMethod();
134+
InvokeExpr invExpr = s.getInvokeExpr();
135+
SootMethod immediate = invExpr.getMethod();
136+
if (fallback == Fallback.CHA && invExpr instanceof InstanceInvokeExpr) {
137+
InstanceInvokeExpr instinv = (InstanceInvokeExpr) invExpr;
138+
FastHierarchy fh = Scene.v().getOrMakeFastHierarchy();
139+
Type t = instinv.getBase().getType();
140+
if (t instanceof RefType) {
141+
RefType rt = (RefType) t;
142+
return fh.resolveAbstractDispatch(rt.getSootClass(), instinv.getMethodRef());
143+
}
144+
}
115145
if (includePhantomCallees || immediate.hasActiveBody()) {
116146
return Collections.singleton(immediate);
117147
}
@@ -191,15 +221,12 @@ public void setIncludePhantomCallees(boolean includePhantomCallees) {
191221
}
192222

193223
/**
194-
* Sets whether methods that operate on the callgraph shall return the immediate callee of a call site if the callgraph has
195-
* no outgoing edges
224+
* Sets the fallback mode. The fallback is used when the call graph reports no outgoing edges.
196225
*
197-
* @param fallbackToImmediateCallees
198-
* True to return the immediate callee if the callgraph does not contain any edges for the respective call site,
199-
* false to return an empty set in such cases
226+
* @param fallbackMode the fallback mode to use
200227
*/
201-
public void setFallbackToImmediateCallees(boolean fallbackToImmediateCallees) {
202-
this.fallbackToImmediateCallees = fallbackToImmediateCallees;
228+
public void setFallbackMode(Fallback fallbackMode) {
229+
this.fallback = fallbackMode;
203230
}
204231

205232
protected EdgeFilter createEdgeFilter() {

0 commit comments

Comments
 (0)