| 1 19 20 package edu.umd.cs.findbugs.ba.npe; 21 22 import java.util.Map ; 23 24 import org.apache.bcel.classfile.Method; 25 import org.apache.bcel.generic.InstructionHandle; 26 import org.apache.bcel.generic.MethodGen; 27 28 import edu.umd.cs.findbugs.SystemProperties; 29 import edu.umd.cs.findbugs.ba.AnalysisContext; 30 import edu.umd.cs.findbugs.ba.AnalysisFeatures; 31 import edu.umd.cs.findbugs.ba.BackwardDataflowAnalysis; 32 import edu.umd.cs.findbugs.ba.BasicBlock; 33 import edu.umd.cs.findbugs.ba.CFG; 34 import edu.umd.cs.findbugs.ba.CFGBuilderException; 35 import edu.umd.cs.findbugs.ba.ClassContext; 36 import edu.umd.cs.findbugs.ba.DFSEdgeTypes; 37 import edu.umd.cs.findbugs.ba.DataflowAnalysisException; 38 import edu.umd.cs.findbugs.ba.DataflowTestDriver; 39 import edu.umd.cs.findbugs.ba.DepthFirstSearch; 40 import edu.umd.cs.findbugs.ba.Edge; 41 import edu.umd.cs.findbugs.ba.EdgeTypes; 42 import edu.umd.cs.findbugs.ba.Location; 43 import edu.umd.cs.findbugs.ba.ReverseDepthFirstSearch; 44 import edu.umd.cs.findbugs.ba.SignatureParser; 45 import edu.umd.cs.findbugs.ba.heap.FieldSet; 46 import edu.umd.cs.findbugs.ba.type.TypeDataflow; 47 import edu.umd.cs.findbugs.ba.vna.ValueNumber; 48 import edu.umd.cs.findbugs.ba.vna.ValueNumberDataflow; 49 import edu.umd.cs.findbugs.ba.vna.ValueNumberFrame; 50 51 59 public class UnconditionalDerefAnalysis extends BackwardDataflowAnalysis<UnconditionalDerefSet> { 60 private static final boolean DEBUG = SystemProperties.getBoolean("npe.deref.debug"); 61 62 private final CFG cfg; 63 private final MethodGen methodGen; 64 private final ValueNumberDataflow vnaDataflow; 66 private final Map <ValueNumber, Integer > valueNumberToParamMap; 67 private final int numParams; 68 71 public UnconditionalDerefAnalysis( 72 ReverseDepthFirstSearch rdfs, 73 DepthFirstSearch dfs, 74 CFG cfg, 75 MethodGen methodGen, 76 ValueNumberDataflow vnaDataflow, 77 TypeDataflow typeDataflow) { 78 super(rdfs, dfs); 79 this.cfg = cfg; 80 this.methodGen = methodGen; 81 this.vnaDataflow = vnaDataflow; 83 this.valueNumberToParamMap = vnaDataflow.getValueNumberToParamMap(methodGen.getSignature(), methodGen.isStatic()); 84 this.numParams = new SignatureParser(methodGen.getSignature()).getNumParameters(); 85 if (DEBUG) System.out.println("Analyzing guaranteed dereferences in " + methodGen.getClassName() + "." + methodGen.getName() + " : " + methodGen.getSignature()); 88 } 89 90 public void copy(UnconditionalDerefSet source, UnconditionalDerefSet dest) { 91 dest.clear(); 92 dest.or(source); 93 } 94 95 public UnconditionalDerefSet createFact() { 96 return new UnconditionalDerefSet(numParams); 97 } 98 99 public void initEntryFact(UnconditionalDerefSet result) throws DataflowAnalysisException { 100 result.clear(); 103 } 104 105 public void initResultFact(UnconditionalDerefSet result) { 106 makeFactTop(result); 107 } 108 109 public void makeFactTop(UnconditionalDerefSet fact) { 110 fact.setTop(); 111 } 112 public boolean isTop(UnconditionalDerefSet fact) { 113 return fact.isTop(); 114 } 115 public void meetInto(UnconditionalDerefSet fact, Edge edge, UnconditionalDerefSet result) throws DataflowAnalysisException { 116 if (AnalysisContext.currentAnalysisContext().getBoolProperty(AnalysisFeatures.ACCURATE_EXCEPTIONS) 118 && edge.isExceptionEdge() 119 && !edge.isFlagSet(EdgeTypes.EXPLICIT_EXCEPTIONS_FLAG)) { 120 return; 121 } 122 123 if (result.isTop() || fact.isBottom()) { 124 copy(fact, result); 125 } else if (result.isBottom() || fact.isTop()) { 126 } else { 128 result.and(fact); 130 } 131 boolean isBackEdge = edge.isBackwardInBytecode(); 132 } 133 134 public boolean same(UnconditionalDerefSet fact1, UnconditionalDerefSet fact2) { 135 return fact1.equals(fact2); 136 } 137 138 @Override  140 public boolean isFactValid(UnconditionalDerefSet fact) { 141 return fact.isValid(); 142 } 143 144 @Override  145 public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, UnconditionalDerefSet fact) 146 throws DataflowAnalysisException { 147 148 if (!fact.isValid()) 149 throw new IllegalStateException (); 150 151 if (handle != basicBlock.getFirstInstruction()) 153 return; 154 BasicBlock fallThroughPredecessor = cfg.getPredecessorWithEdgeType(basicBlock, EdgeTypes.FALL_THROUGH_EDGE); 155 if (fallThroughPredecessor == null || !fallThroughPredecessor.isNullCheck()) 156 return; 157 158 ValueNumberFrame vnaFrame = vnaDataflow.getFactAtLocation(new Location(handle, basicBlock)); 160 if (!vnaFrame.isValid()) { 161 makeFactTop(fact); 164 return; 165 } 166 ValueNumber instance = vnaFrame.getInstance(handle.getInstruction(), methodGen.getConstantPool()); 167 if (DEBUG) { 168 System.out.println("[Null check of value " + instance.getNumber() + "]"); 169 } 170 171 Integer param = valueNumberToParamMap.get(instance); 172 if (param == null) 173 return; 174 175 if (DEBUG) { 176 System.out.println("[Value is a parameter!]"); 177 } 178 fact.set(param.intValue()); 179 } 180 181 public static void main(String [] argv) throws Exception { 182 if (argv.length != 1) { 183 System.err.println("Usage: " + UnconditionalDerefAnalysis.class.getName() + " <class file>"); 184 System.exit(1); 185 } 186 DataflowTestDriver<UnconditionalDerefSet, UnconditionalDerefAnalysis> driver = 187 new DataflowTestDriver<UnconditionalDerefSet, UnconditionalDerefAnalysis>() { 188 @Override  189 public UnconditionalDerefDataflow createDataflow(ClassContext classContext, Method method) 190 throws CFGBuilderException, DataflowAnalysisException { 191 return null; 193 } 194 }; 195 driver.execute(argv[0]); 196 } 197 } | Popular Tags |