private Set<CGNode> findRecursiveMethods(IProgressMonitor progress) throws CancelException {
    CallGraph cg = sdg.getCallGraph();
    GraphReachability<CGNode, CGNode> reach =
        new GraphReachability<CGNode, CGNode>(cg, new TrueFilter());
    progress.subTask("Searching recursive methods");
    reach.solve(progress);

    Set<CGNode> recursive = HashSetFactory.make();

    for (CGNode node : cg) {
      OrdinalSet<CGNode> rset = reach.getReachableSet(node);
      for (CGNode target : rset) {
        if (target != node) {
          OrdinalSet<CGNode> tset = reach.getReachableSet(target);
          if (tset.contains(node)) {
            recursive.add(node);
            break;
          }
        }
      }

      progress.worked(1);
    }

    progress.done();

    return recursive;
  }
Example #2
0
  private static OrdinalSet<InstanceKey> findReachableInstances(
      final PointerAnalysis<InstanceKey> pts, final PointerKey pkStart) {
    final HeapGraph hg = pts.getHeapGraph();
    if (!hg.containsNode(pkStart)) {
      return OrdinalSet.empty();
    }

    final OrdinalSetMapping<InstanceKey> mapping = pts.getInstanceKeyMapping();

    final BitVectorIntSet resultSet = new BitVectorIntSet();

    final NumberedDFSDiscoverTimeIterator<Object> dfsDiscover =
        new NumberedDFSDiscoverTimeIterator<Object>(hg, pkStart);
    while (dfsDiscover.hasNext()) {
      Object obj = dfsDiscover.next();
      if (obj instanceof InstanceKey) {
        InstanceKey ik = (InstanceKey) obj;
        final int ikNum = mapping.getMappedIndex(ik);
        resultSet.add(ikNum);
      }
    }

    final OrdinalSet<InstanceKey> reachable = new OrdinalSet<InstanceKey>(resultSet, mapping);

    return reachable;
  }
  private Set<CallNode> compute(IProgressMonitor progress) throws CancelException {
    Set<CallNode> calls = HashSetFactory.make();

    Set<CGNode> recursive = findRecursiveMethods(progress);

    Set<CGNode> loop = findLoopingMethods(progress);

    CallGraph cg = sdg.getCallGraph();
    Graph<CGNode> inverted = GraphInverter.invert(cg);
    GraphReachability<CGNode, CGNode> reach =
        new GraphReachability<CGNode, CGNode>(inverted, new TrueFilter());
    progress.subTask("Searching potential non-returning calls");
    reach.solve(progress);

    Set<CGNode> roots = HashSetFactory.make(loop);
    roots.addAll(recursive);

    OrdinalSet<CGNode> potential = OrdinalSet.empty();

    for (CGNode root : roots) {
      OrdinalSet<CGNode> reached = reach.getReachableSet(root);
      potential = OrdinalSet.unify(potential, reached);
    }

    Set<CGNode> terminating = HashSetFactory.make();
    Set<CGNode> nonTerminating = HashSetFactory.make();

    for (CGNode node : cg) {
      if (potential.contains(node)) {
        nonTerminating.add(node);
      } else {
        terminating.add(node);
      }
    }

    for (Call call : sdg.getAllCalls()) {
      if (nonTerminating.contains(call.callee.getCallGraphNode())) {
        calls.add(call.node);
      }
    }

    progress.done();

    computeControlDependence(calls, progress);

    return calls;
  }
Example #4
0
 @Test
 public void testZeroOneContainerCopyOf()
     throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
   AnalysisScope scope =
       CallGraphTestUtil.makeJ2SEAnalysisScope(
           TestConstants.WALA_TESTDATA, CallGraphTestUtil.REGRESSION_EXCLUSIONS);
   ClassHierarchy cha = ClassHierarchy.make(scope);
   Iterable<Entrypoint> entrypoints =
       Util.makeMainEntrypoints(scope, cha, "Ldemandpa/TestArraysCopyOf");
   AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
   AnalysisCache cache = new AnalysisCache();
   CallGraphBuilder builder = Util.makeZeroOneContainerCFABuilder(options, cache, cha, scope);
   CallGraph cg = builder.makeCallGraph(options, null);
   PointerAnalysis pa = builder.getPointerAnalysis();
   CGNode mainMethod = AbstractPtrTest.findMainMethod(cg);
   PointerKey keyToQuery = AbstractPtrTest.getParam(mainMethod, "testThisVar", pa.getHeapModel());
   OrdinalSet<? extends InstanceKey> pointsToSet = pa.getPointsToSet(keyToQuery);
   Assert.assertEquals(1, pointsToSet.size());
 }