/** * Creates the union of two ordinal sets. * * @param A ordinal set a * @param B ordinal set b * @return union of a and b * @throws IllegalArgumentException iff A or B is null */ public static <T> OrdinalSet<T> unify(OrdinalSet<T> A, OrdinalSet<T> B) { if (A == null) { throw new IllegalArgumentException("A is null"); } if (B == null) { throw new IllegalArgumentException("B is null"); } if (A.size() != 0 && B.size() != 0) { assert A.mapping.equals(B.mapping); } if (A.S == null) { return (B.S == null) ? OrdinalSet.<T> empty() : new OrdinalSet<>(B.S, B.mapping); } else if (B.S == null) { return new OrdinalSet<>(A.S, A.mapping); } IntSet union = A.S.union(B.S); return new OrdinalSet<>(union, A.mapping); }
/** * @throws NullPointerException if instances is null */ public static <T> Collection<T> toCollection(OrdinalSet<T> instances) { return Iterator2Collection.toSet(instances.iterator()); }
/** * @return the set of all locations read by any callee at a call site. */ private static OrdinalSet<PointerKey> unionHeapLocations(CallGraph cg, CGNode n, SSAAbstractInvokeInstruction call, Map<CGNode, OrdinalSet<PointerKey>> loc) { BitVectorIntSet bv = new BitVectorIntSet(); for (CGNode t : cg.getPossibleTargets(n, call.getCallSite())) { bv.addAll(loc.get(t).getBackingSet()); } return new OrdinalSet<>(bv, loc.get(n).getMapping()); }
/** * @return a new OrdinalSet instances * @throws IllegalArgumentException if A is null */ public static <T> OrdinalSet<T> intersect(OrdinalSet<T> A, OrdinalSet<T> B) { if (A == null) { throw new IllegalArgumentException("A is null"); } if (A.size() != 0 && B.size() != 0) { assert A.mapping.equals(B.mapping); } if (A.S == null || B.S == null) { return new OrdinalSet<>(null, A.mapping); } IntSet isect = A.S.intersection(B.S); return new OrdinalSet<>(isect, A.mapping); }
private OrdinalSet<InstanceKey> computeImplicitPointsToSetAtPi(CGNode node, SSAPiInstruction instruction) { MutableSparseIntSet S = MutableSparseIntSet.makeEmpty(); for (int i = 0; i < instruction.getNumberOfUses(); i++) { int vn = instruction.getUse(i); if (vn != -1) { PointerKey lpk = pointerKeys.getPointerKeyForLocal(node, vn); OrdinalSet pointees = getPointsToSet(lpk); IntSet set = pointees.getBackingSet(); if (set != null) { S.addAll(set); } } } return new OrdinalSet<>(S, instanceKeys); }
private OrdinalSet<InstanceKeyAndState> makeOrdinalSet(IntSet intSet) { // make a copy here, to avoid comodification during iteration // TODO remove the copying, do it only at necessary call sites return new OrdinalSet<>(intSetFactory.makeCopy(intSet), ikAndStates); }
public OrdinalSet<InstanceKey> computeImplicitPointsToSetAtGet(CGNode node, FieldReference field, int refVn, boolean isStatic) { IField f = getCallGraph().getClassHierarchy().resolveField(field); if (f == null) { return OrdinalSet.empty(); } if (isStatic) { PointerKey fKey = pointerKeys.getPointerKeyForStaticField(f); return getPointsToSet(fKey); } else { PointerKey ref = pointerKeys.getPointerKeyForLocal(node, refVn); MutableSparseIntSet S = MutableSparseIntSet.makeEmpty(); OrdinalSet<InstanceKey> refs = getPointsToSet(ref); for (InstanceKey ik : refs) { PointerKey fkey = pointerKeys.getPointerKeyForInstanceField(ik, f); if (fkey != null) { OrdinalSet pointees = getPointsToSet(fkey); IntSet set = pointees.getBackingSet(); if (set != null) { S.addAll(set); } } } return new OrdinalSet<>(S, instanceKeys); } }
/** * @return the set of interesting nodes reachable from n */ public OrdinalSet<S> getReachableSet(Object n) throws IllegalStateException { if (solver == null) { throw new IllegalStateException("must call solve() before calling getReachableSet()"); } BitVectorVariable v = solver.getOut(n); assert v != null : "null variable for node " + n; if (v.getValue() == null) { return OrdinalSet.empty(); } else { return new OrdinalSet<>(v.getValue(), domain); } }
@Override @SuppressWarnings("unchecked") public OrdinalSet<InstanceKey> getPointsToSet(PointerKey key) { if (pointsToMap.isImplicit(key)) { return computeImplicitPointsToSet(key); } // special logic to handle contents of char[] from string constants. if (key instanceof InstanceFieldKey) { InstanceFieldKey ifk = (InstanceFieldKey) key; if (ifk.getInstanceKey() instanceof ConstantKey) { ConstantKey<?> i = (ConstantKey<?>) ifk.getInstanceKey(); if (i.getValue() instanceof String && i.getConcreteType().getClassLoader().getLanguage().equals(Language.JAVA)) { StringConstantCharArray contents = StringConstantCharArray.make((ConstantKey<String>) i); instanceKeys.add(contents); Collection<InstanceKey> singleton = HashSetFactory.make(); singleton.add(contents); return OrdinalSet.toOrdinalSet(singleton, instanceKeys); } } } PointsToSetVariable v = pointsToMap.getPointsToSet(key); if (v == null) { return OrdinalSet.empty(); } else { IntSet S = v.getValue(); return new OrdinalSet<>(S, instanceKeys); } }
public boolean isEmpty() { return size() == 0; }
@Override public void visitNew(SSANewInstruction instruction) { pointsToSet = OrdinalSet.empty(); }
pa.getPointsToSet(new LocalPointerKey(caller, invoke.getUse(0))); if (!ptsUri.isEmpty()) { final InstanceKey uriKey = ptsUri.iterator().next(); final OrdinalSet<InstanceKey> points = pa.getPointsToSet(new LocalPointerKey(caller, invoke.getUse(1))); if (!points.isEmpty()) { final InstanceKey stringKey = points.iterator().next(); final UriAppendString node = new UriAppendString(mapping.getMappedIndex(ik),
@Test public void testZeroLengthArray() 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, TestConstants.ZERO_LENGTH_ARRAY_MAIN); AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); CallGraphBuilder<InstanceKey> builder = Util.makeVanillaZeroOneCFABuilder(Language.JAVA, options, new AnalysisCacheImpl(), cha, scope); CallGraph cg = builder.makeCallGraph(options, null); PointerAnalysis<InstanceKey> pa = builder.getPointerAnalysis(); // System.err.println(pa); HeapModel heapModel = pa.getHeapModel(); CGNode mainNode = cg.getNode( cha.resolveMethod(MethodReference.findOrCreate( TypeReference.findOrCreate(ClassLoaderReference.Application, TestConstants.ZERO_LENGTH_ARRAY_MAIN), Selector.make("main([Ljava/lang/String;)V"))), Everywhere.EVERYWHERE); OrdinalSet<InstanceKey> pointsToSet = pa.getPointsToSet(heapModel.getPointerKeyForLocal(mainNode, 4)); Assert.assertEquals(1, pointsToSet.size()); InstanceKey arrayKey = pointsToSet.iterator().next(); OrdinalSet<InstanceKey> arrayContents = pa.getPointsToSet(heapModel.getPointerKeyForArrayContents(arrayKey)); System.err.println(arrayContents); Assert.assertEquals(0, arrayContents.size()); } }
Assert.assertEquals(2, readVars.size()); Assert.assertEquals("[[Node: <Code body of function Ltests/simple-lexical.js/outer> Context: Everywhere,x], [Node: <Code body of function Ltests/simple-lexical.js/outer> Context: Everywhere,z]]", readVars.toString()); Assert.assertEquals(2, writtenVars.size()); Assert.assertEquals("[[Node: <Code body of function Ltests/simple-lexical.js/outer> Context: Everywhere,x], [Node: <Code body of function Ltests/simple-lexical.js/outer> Context: Everywhere,z]]", writtenVars.toString()); Assert.assertEquals(4, readVars.size()); for(Pair<CGNode, String> rv : readVars) { Assert.assertTrue(rv.toString(),
/** * Do all callees corresponding to the given call site def the pointer key being tracked by r? */ private static boolean allCalleesMod(CallGraph cg, HeapReturnCaller r, Map<CGNode, OrdinalSet<PointerKey>> mod) { Collection<CGNode> targets = cg.getPossibleTargets(r.getNode(), r.getCall().getCallSite()); if (targets.isEmpty()) { return false; } for (CGNode t : targets) { if (!mod.get(t).contains(r.getLocation())) { return false; } } return true; }
private Set<CodeElement> getArrayRefCodeElts(CGNode node, SSAArrayReferenceInstruction inst) { Set<CodeElement> elts = HashSetFactory.make(); final PointerKey pk = pa.getHeapModel().getPointerKeyForLocal(node, inst.getArrayRef()); final OrdinalSet<InstanceKey> pointsToSet = pa.getPointsToSet(pk); if (pointsToSet.isEmpty()) { TypeReference arrayType = TypeReference.findOrCreateArrayOf(inst .getElementType()); InstanceKey ik = new ConcreteTypeKey(pa.getClassHierarchy() .lookupClass(arrayType)); elts.add(new InstanceKeyElement(ik)); } else { for (InstanceKey ik : pointsToSet) { elts.add(new InstanceKeyElement(ik)); } } return elts; }
private OrdinalSet<InstanceKey> computeImplicitPointsToSetAtPi(CGNode node, SSAPiInstruction instruction) { MutableSparseIntSet S = MutableSparseIntSet.makeEmpty(); for (int i = 0; i < instruction.getNumberOfUses(); i++) { int vn = instruction.getUse(i); if (vn != -1) { PointerKey lpk = pointerKeys.getPointerKeyForLocal(node, vn); OrdinalSet pointees = getPointsToSet(lpk); IntSet set = pointees.getBackingSet(); if (set != null) { S.addAll(set); } } } return new OrdinalSet<>(S, instanceKeys); }
private OrdinalSet<InstanceKeyAndState> makeOrdinalSet(IntSet intSet) { // make a copy here, to avoid comodification during iteration // TODO remove the copying, do it only at necessary call sites return new OrdinalSet<>(intSetFactory.makeCopy(intSet), ikAndStates); }
public OrdinalSet<InstanceKey> computeImplicitPointsToSetAtGet(CGNode node, FieldReference field, int refVn, boolean isStatic) { IField f = getCallGraph().getClassHierarchy().resolveField(field); if (f == null) { return OrdinalSet.empty(); } if (isStatic) { PointerKey fKey = pointerKeys.getPointerKeyForStaticField(f); return getPointsToSet(fKey); } else { PointerKey ref = pointerKeys.getPointerKeyForLocal(node, refVn); MutableSparseIntSet S = MutableSparseIntSet.makeEmpty(); OrdinalSet<InstanceKey> refs = getPointsToSet(ref); for (InstanceKey ik : refs) { PointerKey fkey = pointerKeys.getPointerKeyForInstanceField(ik, f); if (fkey != null) { OrdinalSet pointees = getPointsToSet(fkey); IntSet set = pointees.getBackingSet(); if (set != null) { S.addAll(set); } } } return new OrdinalSet<>(S, instanceKeys); } }