use of soot.toolkits.exceptions.ThrowableSet.Pair in project soot by Sable.
the class UnitThrowAnalysis method mightThrow.
/**
* Returns the set of types that might be thrown as a result of
* calling the specified method.
*
* @param sm method whose exceptions are to be returned.
* @param doneSet The set of methods that were already processed
*
* @return a representation of the set of {@link
* java.lang.Throwable Throwable} types that <code>m</code> might
* throw.
*/
private ThrowableSet mightThrow(SootMethod sm, Set<SootMethod> doneSet) {
// Do not run in loops
if (!doneSet.add(sm))
return ThrowableSet.Manager.v().EMPTY;
// unsound, but would otherwise always bloat our result set.
if (!sm.hasActiveBody())
return ThrowableSet.Manager.v().EMPTY;
// We need a mapping between unit and exception
final PatchingChain<Unit> units = sm.getActiveBody().getUnits();
Map<Unit, Collection<Trap>> unitToTraps = sm.getActiveBody().getTraps().isEmpty() ? null : new HashMap<Unit, Collection<Trap>>();
for (Trap t : sm.getActiveBody().getTraps()) {
for (Iterator<Unit> unitIt = units.iterator(t.getBeginUnit(), units.getPredOf(t.getEndUnit())); unitIt.hasNext(); ) {
Unit unit = unitIt.next();
Collection<Trap> unitsForTrap = unitToTraps.get(unit);
if (unitsForTrap == null) {
unitsForTrap = new ArrayList<Trap>();
unitToTraps.put(unit, unitsForTrap);
}
unitsForTrap.add(t);
}
}
ThrowableSet methodSet = ThrowableSet.Manager.v().EMPTY;
if (sm.hasActiveBody()) {
Body methodBody = sm.getActiveBody();
for (Unit u : methodBody.getUnits()) {
if (u instanceof Stmt) {
Stmt stmt = (Stmt) u;
ThrowableSet curStmtSet;
if (stmt.containsInvokeExpr()) {
InvokeExpr inv = stmt.getInvokeExpr();
curStmtSet = mightThrow(inv.getMethod(), doneSet);
} else
curStmtSet = mightThrow(u);
// The exception might be caught along the way
if (unitToTraps != null) {
Collection<Trap> trapsForUnit = unitToTraps.get(stmt);
if (trapsForUnit != null)
for (Trap t : trapsForUnit) {
Pair p = curStmtSet.whichCatchableAs(t.getException().getType());
curStmtSet = curStmtSet.remove(p.getCaught());
}
}
methodSet = methodSet.add(curStmtSet);
}
}
}
return methodSet;
}
Aggregations