/** * Check properties of the InterproceduralCFG * * @param cg */ private static void checkICFG(CallGraph cg) { InterproceduralCFG icfg = new InterproceduralCFG(cg); try { GraphIntegrity.check(icfg); } catch (UnsoundGraphException e) { e.printStackTrace(); Assert.assertTrue(false); } // perform a little icfg exercise int count = 0; for (Iterator<BasicBlockInContext<ISSABasicBlock>> it = icfg.iterator(); it.hasNext(); ) { BasicBlockInContext<ISSABasicBlock> bb = it.next(); if (icfg.hasCall(bb)) { count++; } } }
/** * TODO: refactor this to avoid excessive code bloat. * * @throws CancelException * @throws IllegalArgumentException */ public static void doCallGraphs( AnalysisOptions options, AnalysisCache cache, IClassHierarchy cha, AnalysisScope scope, boolean testPAToString) throws IllegalArgumentException, CancelException { // /////////////// // // RTA ///// // /////////////// CallGraph cg = CallGraphTestUtil.buildRTA(options, cache, cha, scope); try { GraphIntegrity.check(cg); } catch (UnsoundGraphException e1) { e1.printStackTrace(); Assert.assertTrue(e1.getMessage(), false); } Set<MethodReference> rtaMethods = CallGraphStats.collectMethods(cg); System.err.println("RTA methods reached: " + rtaMethods.size()); System.err.println(CallGraphStats.getStats(cg)); System.err.println("RTA warnings:\n"); // /////////////// // // 0-CFA ///// // /////////////// cg = CallGraphTestUtil.buildZeroCFA(options, cache, cha, scope, testPAToString); // FIXME: annoying special cases caused by clone2assign mean using // the rta graph for proper graph subset checking does not work. // (note that all the other such checks do use proper graph subset) Graph<MethodReference> squashZero = checkCallGraph(cg, null, rtaMethods, "0-CFA"); // test Pretransitive 0-CFA // not currently supported // warnings = new WarningSet(); // options.setUsePreTransitiveSolver(true); // CallGraph cgP = CallGraphTestUtil.buildZeroCFA(options, cha, scope, // warnings); // options.setUsePreTransitiveSolver(false); // Graph squashPT = checkCallGraph(warnings, cgP, squashZero, null, "Pre-T // 1"); // checkCallGraph(warnings, cg, squashPT, null, "Pre-T 2"); // /////////////// // // 0-1-CFA /// // /////////////// cg = CallGraphTestUtil.buildZeroOneCFA(options, cache, cha, scope, testPAToString); Graph<MethodReference> squashZeroOne = checkCallGraph(cg, squashZero, null, "0-1-CFA"); // /////////////////////////////////////////////////// // // 0-CFA augmented to disambiguate containers /// // /////////////////////////////////////////////////// cg = CallGraphTestUtil.buildZeroContainerCFA(options, cache, cha, scope); Graph<MethodReference> squashZeroContainer = checkCallGraph(cg, squashZero, null, "0-Container-CFA"); // /////////////////////////////////////////////////// // // 0-1-CFA augmented to disambiguate containers /// // /////////////////////////////////////////////////// cg = CallGraphTestUtil.buildZeroOneContainerCFA(options, cache, cha, scope); checkCallGraph(cg, squashZeroContainer, null, "0-1-Container-CFA"); checkCallGraph(cg, squashZeroOne, null, "0-1-Container-CFA"); // test ICFG checkICFG(cg); return; // ///////////// // // 1-CFA /// // ///////////// // warnings = new WarningSet(); // cg = buildOneCFA(); }