@Override public boolean equals(Object obj) { if (obj == null) { return false; } if (obj.getClass() == this.getClass()) { IntPair p = (IntPair) obj; return p.getX() == x && p.getY() == y; } return false; }
@Override public boolean equals(Object obj) { if (obj == null) { return false; } if (obj.getClass() == this.getClass()) { IntPair p = (IntPair) obj; return p.getX() == x && p.getY() == y; } return false; }
@Override public boolean equals(Object obj) { if (obj == null) { return false; } if (obj.getClass() == this.getClass()) { IntPair p = (IntPair) obj; return p.getX() == x && p.getY() == y; } return false; }
@Override public AbstractStatement next() { IntPair p = innerDelegate.next(); int lhs = p.getX(); int rhs = p.getY(); UnaryStatement result = currentOperator.makeEquation((PointsToSetVariable) delegateGraph.getNode(lhs), (PointsToSetVariable) delegateGraph.getNode(rhs)); if (!innerDelegate.hasNext()) { advanceOuter(); } return result; }
@Override public AbstractStatement next() { IntPair p = innerDelegate.next(); int lhs = p.getX(); int rhs = p.getY(); UnaryStatement result = currentOperator.makeEquation((PointsToSetVariable) delegateGraph.getNode(lhs), (PointsToSetVariable) delegateGraph.getNode(rhs)); if (!innerDelegate.hasNext()) { advanceOuter(); } return result; }
/** * Note: This is inefficient. Use with care. * * @param s_p local block number an entry * @param x local block number of an exit block * @param d2 target dataflow fact * @return set of d1 s.t. d1 -> d2 recorded as a summary edge for (s_p,x), or null if none */ public IntSet getInvertedSummaryEdgesForTarget(int s_p, int x, int d2) { int n = getIndexForEntryExitPair(s_p, x); IBinaryNaturalRelation R = summaries.get(n); if (R == null) { return null; } else { MutableSparseIntSet result = MutableSparseIntSet.makeEmpty(); for (IntPair p : R) { if (p.getY() == d2) { result.add(p.getX()); } } return result; } }
/** * Note: This is inefficient. Use with care. * * @param s_p local block number an entry * @param x local block number of an exit block * @param d2 target dataflow fact * @return set of d1 s.t. d1 -> d2 recorded as a summary edge for (s_p,x), or null if none */ public IntSet getInvertedSummaryEdgesForTarget(int s_p, int x, int d2) { int n = getIndexForEntryExitPair(s_p, x); IBinaryNaturalRelation R = summaries.get(n); if (R == null) { return null; } else { MutableSparseIntSet result = MutableSparseIntSet.makeEmpty(); for (IntPair p : R) { if (p.getY() == d2) { result.add(p.getX()); } } return result; } }
/** * @param pc a program counter (index into ShrikeBT instruction array) * @param vn a value number * @return if we know that immediately after the given program counter, v_vn corresponds to some set of locals, then return an * array of the local numbers. else return null. */ private int[] findLocalsForValueNumber(int pc, int vn) { if (vn < 0) { return null; } IBasicBlock bb = shrikeCFG.getBlockForInstruction(pc); int firstInstruction = bb.getFirstInstructionIndex(); // walk forward from the first instruction to reconstruct the // state of the locals at this pc int[] locals = block2LocalState[bb.getNumber()]; for (int i = firstInstruction; i <= pc; i++) { if (localStoreMap[i] != null) { IntPair p = localStoreMap[i]; locals = setLocal(locals, p.getY(), p.getX()); } } return locals == null ? null : extractIndices(locals, vn); }
/** * @param pc a program counter (index into ShrikeBT instruction array) * @param vn a value number * @return if we know that immediately after the given program counter, v_vn corresponds to some set of locals, then return an * array of the local numbers. else return null. */ private int[] findLocalsForValueNumber(int pc, int vn) { IBasicBlock<Instruction> bb = dexCFG.getBlockForInstruction(pc); int firstInstruction = bb.getFirstInstructionIndex(); // walk forward from the first instruction to reconstruct the // state of the locals at this pc int[] locals = block2LocalState[bb.getNumber()]; if (locals == null) { locals = allocateNewLocalsArray(); } for (int i = firstInstruction; i <= pc; i++) { if (localStoreMap[i] != null) { IntPair p = localStoreMap[i]; locals[p.getY()] = p.getX(); } } return extractIndices(locals, vn); }
/** * @param pc a program counter (index into ShrikeBT instruction array) * @param vn a value number * @return if we know that immediately after the given program counter, v_vn corresponds to some set of locals, then return an * array of the local numbers. else return null. */ private int[] findLocalsForValueNumber(int pc, int vn) { if (vn < 0) { return null; } IBasicBlock bb = shrikeCFG.getBlockForInstruction(pc); int firstInstruction = bb.getFirstInstructionIndex(); // walk forward from the first instruction to reconstruct the // state of the locals at this pc int[] locals = block2LocalState[bb.getNumber()]; for (int i = firstInstruction; i <= pc; i++) { if (localStoreMap[i] != null) { IntPair p = localStoreMap[i]; locals = setLocal(locals, p.getY(), p.getX()); } } return locals == null ? null : extractIndices(locals, vn); }
/** * @param pc a program counter (index into ShrikeBT instruction array) * @param vn a value number * @return if we know that immediately after the given program counter, v_vn corresponds to some set of locals, then return an * array of the local numbers. else return null. */ private int[] findLocalsForValueNumber(int pc, int vn) { IBasicBlock<Instruction> bb = dexCFG.getBlockForInstruction(pc); int firstInstruction = bb.getFirstInstructionIndex(); // walk forward from the first instruction to reconstruct the // state of the locals at this pc int[] locals = block2LocalState[bb.getNumber()]; if (locals == null) { locals = allocateNewLocalsArray(); } for (int i = firstInstruction; i <= pc; i++) { if (localStoreMap[i] != null) { IntPair p = localStoreMap[i]; locals[p.getY()] = p.getX(); } } return extractIndices(locals, vn); }
public NullPointerFrameWork(ControlFlowGraph<SSAInstruction, T> cfg, IR ir) { final IBinaryNaturalRelation backEdges = Acyclic.computeBackEdges(cfg, cfg.entry()); boolean hasBackEdge = backEdges.iterator().hasNext(); if (hasBackEdge) { MutableCFG<SSAInstruction, T> cfg2 = MutableCFG.copyFrom(cfg); for (IntPair edge : backEdges) { T from = cfg2.getNode(edge.getX()); T to = cfg2.getNode(edge.getY()); cfg2.removeEdge(from, to); cfg2.addEdge(from, cfg.exit()); } this.flow = cfg2; } else { this.flow = cfg; } this.transferFunct = new NullPointerTransferFunctionProvider<>(cfg, ir); }
public NullPointerFrameWork(ControlFlowGraph<SSAInstruction, T> cfg, IR ir) { final IBinaryNaturalRelation backEdges = Acyclic.computeBackEdges(cfg, cfg.entry()); boolean hasBackEdge = backEdges.iterator().hasNext(); if (hasBackEdge) { MutableCFG<SSAInstruction, T> cfg2 = MutableCFG.copyFrom(cfg); for (IntPair edge : backEdges) { T from = cfg2.getNode(edge.getX()); T to = cfg2.getNode(edge.getY()); cfg2.removeEdge(from, to); cfg2.addEdge(from, cfg.exit()); } this.flow = cfg2; } else { this.flow = cfg; } this.transferFunct = new NullPointerTransferFunctionProvider<>(cfg, ir); }
@Test public void testNList() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException { AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA, CallGraphTestUtil.REGRESSION_EXCLUSIONS); ClassHierarchy cha = ClassHierarchyFactory.make(scope); Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, "Lrecurse/NList"); AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); CallGraph cg = CallGraphTestUtil.buildZeroCFA(options, new AnalysisCacheImpl(), cha, scope, false); IBinaryNaturalRelation backEdges = Acyclic.computeBackEdges(cg, cg.getFakeRootNode()); Assert.assertTrue("NList should have cycles", backEdges.iterator().hasNext()); Map<CGNode, Set<CGNode>> cgBackEdges = HashMapFactory.make(); for (IntPair p : backEdges) { CGNode src = cg.getNode(p.getX()); if (!cgBackEdges.containsKey(src)) { cgBackEdges.put(src, HashSetFactory.<CGNode>make()); } cgBackEdges.get(src).add(cg.getNode(p.getY())); } PrunedCallGraph pcg = new PrunedCallGraph(cg, Iterator2Collection.toSet(cg.iterator()), cgBackEdges); Assert.assertTrue("cycles should be gone", !Acyclic.computeBackEdges(pcg, pcg.getFakeRootNode()).iterator().hasNext()); }