/** * Returns basic block that contains the statement, or null. If id stmt, it looks in tag of first * non-id stmt. */ public static Block getBB(Stmt s) { Block bb; // 2010-02-26: return null when s == null if (s != null) { // move to first non-id stmt Stmt sNonId = s; if (sNonId instanceof IdentityStmt) { PatchingChain pchain = ProgramFlowGraph.inst().getContainingMethod(sNonId).retrieveActiveBody().getUnits(); do { sNonId = (Stmt) pchain.getSuccOf(sNonId); } while (sNonId instanceof IdentityStmt); } // retrieve basic block for non-id stmt StmtTag sTag = (StmtTag) sNonId.getTag(StmtTag.TAG_NAME); bb = sTag.getBasicBlock(); } else { bb = null; } return bb; }
public boolean DoAnalysis(boolean verbose) { Stack<List<Set<SootClass>>> current_exception_sets = new Stack<List<Set<SootClass>>>(); { List<Set<SootClass>> exception_sets = new ArrayList<Set<SootClass>>(); exception_sets.add(method_exception_set); current_exception_sets.push(exception_sets); } PatchingChain<Unit> chain = body.getUnits(); Unit next = chain.getFirst(); int previous_class_count = method_exception_set.size(); for (Map.Entry<Unit, List<TwoValuePair<Trap, Set<SootClass>>>> entry : trap_begin_exception_sets.entrySet()) { for (TwoValuePair<Trap, Set<SootClass>> tvp : entry.getValue()) { previous_class_count += tvp.w.size(); } } do { if (trap_begin_exception_sets.containsKey(next)) { List<TwoValuePair<Trap, Set<SootClass>>> tvps = trap_begin_exception_sets.get(next); List<Set<SootClass>> sets_to_add = new ArrayList<Set<SootClass>>(); for (TwoValuePair<Trap, Set<SootClass>> tvp : tvps) { sets_to_add.add(tvp.w); } current_exception_sets.push(sets_to_add); } if (next instanceof InvokeStmt || next instanceof AssignStmt) { SootMethod callee = null; if (next instanceof AssignStmt) { if (((AssignStmt) next).getRightOp() instanceof InvokeExpr) { callee = ((InvokeExpr) ((AssignStmt) next).getRightOp()).getMethod(); } } else { callee = ((InvokeStmt) next).getInvokeExpr().getMethod(); } if (callee != null) { // invocation only Collection<SootClass> exception_classes; if (class_map.containsKey(callee.getDeclaringClass())) { assert class_map.get(callee.getDeclaringClass()).method_analysis.containsKey(callee); exception_classes = class_map .get(callee.getDeclaringClass()) .method_analysis .get(callee) .method_exception_set; } else { exception_classes = callee.getExceptions(); } for (SootClass exception_class : exception_classes) { for (Set<SootClass> current_exception_set : current_exception_sets.peek()) { current_exception_set.add(exception_class); } } } } else if (next instanceof ThrowStmt) { assert chain.getPredOf(next) instanceof JInvokeStmt; assert ((JInvokeStmt) chain.getPredOf(next)).getInvokeExpr() instanceof SpecialInvokeExpr; assert ((SpecialInvokeExpr) ((JInvokeStmt) chain.getPredOf(next)).getInvokeExpr()).getBase() instanceof JimpleLocal; assert ((JimpleLocal) ((SpecialInvokeExpr) ((JInvokeStmt) chain.getPredOf(next)).getInvokeExpr()) .getBase()) .getType() instanceof RefType; SootClass exception_class = ((RefType) ((JimpleLocal) ((SpecialInvokeExpr) ((JInvokeStmt) chain.getPredOf(next)).getInvokeExpr()) .getBase()) .getType()) .getSootClass(); for (Set<SootClass> current_exception_set : current_exception_sets.peek()) { current_exception_set.add(exception_class); } } if (trap_end_exception_sets.containsKey(next)) { List<TwoValuePair<Trap, Set<SootClass>>> tvps = trap_end_exception_sets.get(next); if (verbose) { for (Set<SootClass> current_exception_set : current_exception_sets.peek()) { if (current_exception_set.size() == 0) { for (TwoValuePair<Trap, Set<SootClass>> tvp : tvps) { if (!tvp.v.getException().getName().equals("java.lang.RuntimeException")) System.out.println( "Warning: In " + method.toString() + ": Unncessary exception handler for catching " + tvp.v.getException().getName()); } } } } for (TwoValuePair<Trap, Set<SootClass>> tvp : tvps) { Iterator<SootClass> i = tvp.w.iterator(); while (i.hasNext()) { SootClass exception_class = i.next(); if (tvp.v.getException() == exception_class) { // getting properly caught by the handler. i.remove(); } else { SootClass super_exception_class = exception_class; while (super_exception_class != null) { if (tvp.v.getException() == super_exception_class) { i.remove(); if (verbose && super_exception_class != exception_class && GetMostRestrictiveFormOfException(tvps, exception_class) == tvp.v.getException() && !super_exception_class.getName().equals("java.lang.RuntimeException")) { System.out.println( "Warning: In " + method.toString() + ": attempting to catch " + exception_class.getName() + " with " + super_exception_class.getName() + " Consider catching the most restrictive exception class"); } break; } try { super_exception_class = super_exception_class.getSuperclass(); } catch ( RuntimeException e) { // unfortunately soot doesn't have a specific exception class for "no // superclass for java.lang.Object" exception super_exception_class = null; } } } } } current_exception_sets.pop(); for (Set<SootClass> current_exception_set : current_exception_sets .peek()) { // This list iteration is not necessary if we are still making the // assumption that there's only one unique set that contains exception // classes if the range for traps are the same for (TwoValuePair<Trap, Set<SootClass>> tvp : tvps) { for (SootClass exception_class : tvp.w) { current_exception_set.add(exception_class); } } } } next = chain.getSuccOf(next); } while (next != null); int new_class_count = method_exception_set.size(); for (Map.Entry<Unit, List<TwoValuePair<Trap, Set<SootClass>>>> entry : trap_begin_exception_sets.entrySet()) { for (TwoValuePair<Trap, Set<SootClass>> tvp : entry.getValue()) { new_class_count += tvp.w.size(); } } return new_class_count != previous_class_count; }