1 19 20 package edu.umd.cs.findbugs.ba; 21 22 import java.util.HashSet ; 23 import java.util.Iterator ; 24 import java.util.LinkedList ; 25 import java.util.List ; 26 import java.util.Set ; 27 28 import org.apache.bcel.Repository; 29 import org.apache.bcel.generic.MethodGen; 30 31 import edu.umd.cs.findbugs.SystemProperties; 32 import edu.umd.cs.findbugs.ba.type.ExceptionSet; 33 import edu.umd.cs.findbugs.ba.type.TypeAnalysis; 34 import edu.umd.cs.findbugs.ba.type.TypeDataflow; 35 36 46 public class PruneInfeasibleExceptionEdges implements EdgeTypes { 47 private static final boolean DEBUG = SystemProperties.getBoolean("cfg.prune.debug"); 48 private static final boolean STATS = SystemProperties.getBoolean("cfg.prune.stats"); 49 private static int numEdgesPruned = 0; 50 51 static { 52 if (STATS) { 53 Runtime.getRuntime().addShutdownHook(new Thread () { 54 @Override 55 public void run() { 56 System.err.println("Exception edges pruned: " + numEdgesPruned); 57 } 58 }); 59 } 60 } 61 62 71 private static class MarkedEdge { 72 private Edge edge; 73 private int flag; 74 75 public MarkedEdge(Edge edge, int flag) { 76 this.edge = edge; 77 this.flag = flag; 78 } 79 80 public void apply() { 81 int flags = edge.getFlags(); 82 flags |= this.flag; 83 edge.setFlags(flags); 84 } 85 } 86 87 private CFG cfg; 88 private TypeDataflow typeDataflow; 89 private boolean cfgModified; 90 91 99 public PruneInfeasibleExceptionEdges(CFG cfg, MethodGen methodGen, TypeDataflow typeDataflow) { 100 this.cfg = cfg; 101 this.typeDataflow = typeDataflow; 102 } 103 104 114 public void execute() throws ClassNotFoundException { 115 Set <Edge> deletedEdgeSet = new HashSet <Edge>(); 116 List <MarkedEdge> markedEdgeList = new LinkedList <MarkedEdge>(); 117 118 for (Iterator <Edge> i = cfg.edgeIterator(); i.hasNext();) { 121 Edge edge = i.next(); 122 if (!edge.isExceptionEdge()) 123 continue; 124 125 ExceptionSet exceptionSet = typeDataflow.getEdgeExceptionSet(edge); 126 if (exceptionSet.isEmpty()) { 127 deletedEdgeSet.add(edge); 130 } else { 131 if (exceptionSet.isSingleton("java.lang.CloneNotSupportedException") && cfg.getMethodName().endsWith(".clone()")){ 132 String className = cfg.getMethodGen().getClassName(); 133 if (Repository.implementationOf(className,"java.lang.Cloneable")) { 134 deletedEdgeSet.add(edge); 135 continue; 136 } 137 } 138 boolean someChecked = exceptionSet.containsCheckedExceptions(); 143 boolean someExplicit = exceptionSet.containsExplicitExceptions(); 144 145 int flags = 0; 146 if (someChecked) flags |= CHECKED_EXCEPTIONS_FLAG; 147 if (someExplicit) flags |= EXPLICIT_EXCEPTIONS_FLAG; 148 149 markedEdgeList.add(new MarkedEdge(edge, flags)); 150 } 151 } 152 153 for (Edge edge : deletedEdgeSet) { 155 cfg.removeEdge(edge); 156 if (STATS) ++numEdgesPruned; 157 cfgModified = true; 158 } 159 160 for (MarkedEdge markedEdge : markedEdgeList) { 162 markedEdge.apply(); 163 } 164 } 165 166 169 public boolean wasCFGModified() { 170 return cfgModified; 171 } 172 } 173 174 | Popular Tags |