/** flow function for normal intraprocedural edges */ public IUnaryFlowFunction getNormalFlowFunction( final BasicBlockInContext<IExplodedBasicBlock> src, BasicBlockInContext<IExplodedBasicBlock> dest) { final IExplodedBasicBlock ebb = src.getDelegate(); SSAInstruction instruction = ebb.getInstruction(); if (instruction instanceof SSAPutInstruction) { final SSAPutInstruction putInstr = (SSAPutInstruction) instruction; if (putInstr.isStatic()) { return new IUnaryFlowFunction() { public IntSet getTargets(int d1) { // first, gen this statement int factNum = domain.getMappedIndex(Pair.make(src.getNode(), ebb.getFirstInstructionIndex())); assert factNum != -1; MutableSparseIntSet result = MutableSparseIntSet.makeEmpty(); result.add(factNum); // if incoming statement is some different statement that defs the same static field, // kill it; otherwise, keep it if (d1 != factNum) { IField staticField = cha.resolveField(putInstr.getDeclaredField()); assert staticField != null; Pair<CGNode, Integer> otherPutInstrAndNode = domain.getMappedObject(d1); SSAPutInstruction otherPutInstr = (SSAPutInstruction) otherPutInstrAndNode.fst.getIR() .getInstructions()[otherPutInstrAndNode.snd]; IField otherStaticField = cha.resolveField(otherPutInstr.getDeclaredField()); if (!staticField.equals(otherStaticField)) { result.add(d1); } } return result; } public String toString() { return "Reaching Defs Normal Flow"; } }; } } // identity function when src block isn't for a putstatic return IdentityFlowFunction.identity(); }
/** flow function from caller to callee; just the identity function */ public IUnaryFlowFunction getCallFlowFunction( BasicBlockInContext<IExplodedBasicBlock> src, BasicBlockInContext<IExplodedBasicBlock> dest, BasicBlockInContext<IExplodedBasicBlock> ret) { return IdentityFlowFunction.identity(); }
/** * the flow function for flow from a callee to caller where there was no flow from caller to * callee; just the identity function * * @see ReachingDefsProblem */ public IFlowFunction getUnbalancedReturnFlowFunction( BasicBlockInContext<IExplodedBasicBlock> src, BasicBlockInContext<IExplodedBasicBlock> dest) { return IdentityFlowFunction.identity(); }
/** * flow function from call node to return node when there are no targets for the call site; not * a case we are expecting */ public IUnaryFlowFunction getCallNoneToReturnFlowFunction( BasicBlockInContext<IExplodedBasicBlock> src, BasicBlockInContext<IExplodedBasicBlock> dest) { // if we're missing callees, just keep what information we have return IdentityFlowFunction.identity(); }