예제 #1
0
 @Test
 public void testStaticInit()
     throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
   AnalysisScope scope =
       CallGraphTestUtil.makeJ2SEAnalysisScope(
           TestConstants.WALA_TESTDATA, CallGraphTestUtil.REGRESSION_EXCLUSIONS);
   ClassHierarchy cha = ClassHierarchy.make(scope);
   Iterable<Entrypoint> entrypoints =
       com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(
           scope, cha, "LstaticInit/TestStaticInit");
   AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
   CallGraph cg = CallGraphTestUtil.buildZeroCFA(options, new AnalysisCache(), cha, scope, false);
   boolean foundDoNothing = false;
   for (CGNode n : cg) {
     if (n.toString().contains("doNothing")) {
       foundDoNothing = true;
       break;
     }
   }
   Assert.assertTrue(foundDoNothing);
   options.setHandleStaticInit(false);
   cg = CallGraphTestUtil.buildZeroCFA(options, new AnalysisCache(), cha, scope, false);
   for (CGNode n : cg) {
     Assert.assertTrue(!n.toString().contains("doNothing"));
   }
 }
예제 #2
0
  private Set<CGNode> findLoopingMethods(IProgressMonitor progress) throws CancelException {
    CallGraph cg = sdg.getCallGraph();
    Set<CGNode> loops = HashSetFactory.make();

    progress.subTask("Searching methods with potential endless loops");

    for (CGNode node : cg) {
      IR ir = node.getIR();
      if (ir != null) {
        ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg = ir.getControlFlowGraph();
        final boolean ac = Acyclic.isAcyclic(cfg, cfg.entry());
        if (!ac && !loopsAreSimple(ir)) {
          loops.add(node);
        }
      } else {
        // Conservatively assume that methods may not terminate, iff we dont
        // have their code
        loops.add(node);
      }

      progress.worked(1);
    }

    progress.done();

    return loops;
  }
 private void addParamEdges(LocalPointerKey pk, CGNode node) {
   // get parameter position: value number - 1?
   int paramPos = pk.getValueNumber() - 1;
   // iterate over callers
   for (CGNode caller : cg) {
     // TODO we don't need to add the graph if null is passed
     // as the argument
     addSubgraphForNode(caller);
     IR ir = caller.getIR();
     for (Iterator<CallSiteReference> iterator = ir.iterateCallSites(); iterator.hasNext(); ) {
       CallSiteReference call = iterator.next();
       if (cg.getPossibleTargets(caller, call).contains(node)) {
         SSAAbstractInvokeInstruction[] callInstrs = ir.getCalls(call);
         for (int i = 0; i < callInstrs.length; i++) {
           SSAAbstractInvokeInstruction callInstr = callInstrs[i];
           PointerKey actualPk =
               heapModel.getPointerKeyForLocal(caller, callInstr.getUse(paramPos));
           assert containsNode(actualPk);
           assert containsNode(pk);
           addEdge(pk, actualPk);
         }
       }
     }
   }
 }
  protected void unconditionallyAddConstraintsFromNode(CGNode node) {

    if (DEBUG) {
      System.err.println(("Visiting CGNode " + node));
    }

    if (SSAPropagationCallGraphBuilder.PERIODIC_WIPE_SOFT_CACHES) {
      wipeCount++;
      if (wipeCount >= SSAPropagationCallGraphBuilder.WIPE_SOFT_CACHE_INTERVAL) {
        wipeCount = 0;
        ReferenceCleanser.clearSoftCaches();
      }
    }

    IR ir = node.getIR();
    debugPrintIR(ir);

    if (ir == null) {
      return;
    }

    DefUse du = node.getDU();
    addNodeInstructionConstraints(node, ir, du);
    addNodePassthruExceptionConstraints(node, ir);
  }
예제 #5
0
  /** check that the types of all instance keys are assignable to declared type of pointer key */
  private void checkTypes(IntSet b) {
    assert PARANOID;
    if (b == null) return;
    if (!(pointerKey instanceof LocalPointerKey)) {
      return;
    }
    final LocalPointerKey lpk = (LocalPointerKey) pointerKey;
    CGNode node = lpk.getNode();
    final IClassHierarchy cha = node.getClassHierarchy();
    final IR ir = node.getIR();
    if (ir == null) return;
    TypeInference ti = TypeInference.make(ir, false);
    final IClass type = ti.getType(lpk.getValueNumber()).getType();
    if (type == null) return;
    // don't perform checking for exception variables
    if (cha.isAssignableFrom(cha.lookupClass(TypeReference.JavaLangThrowable), type)) {
      return;
    }
    b.foreach(
        new IntSetAction() {

          public void act(int x) {
            InstanceKey ik = instanceKeys.getMappedObject(x);
            IClass concreteType = ik.getConcreteType();
            if (!cha.isAssignableFrom(type, concreteType)) {
              System.err.println("BOOM");
              System.err.println(ir);
              System.err.println(lpk + " type " + type);
              System.err.println(ik + " type " + concreteType);
              Assertions.UNREACHABLE();
            }
          }
        });
  }
 private boolean exceedsRecursionBound(Context baseContext, int curLevel) {
   if (curLevel > recursionBound) {
     return true;
   }
   // we just do a case analysis here. we might have to add cases later to
   // account for new types of context / recursion.
   CGNode callerNode = (CGNode) baseContext.get(ContextKey.CALLER);
   if (callerNode != null && exceedsRecursionBound(callerNode.getContext(), curLevel + 1)) {
     return true;
   }
   for (int i = 0; i < MAX_INTERESTING_PARAM; i++) {
     FilteredPointerKey.SingleInstanceFilter filter =
         (SingleInstanceFilter) baseContext.get(ContextKey.PARAMETERS[i]);
     if (filter != null) {
       InstanceKey ik = filter.getInstance();
       if (ik instanceof ScopeMappingInstanceKey) {
         ik = ((ScopeMappingInstanceKey) ik).getBase();
       }
       if (ik instanceof InstanceKeyWithNode) {
         if (exceedsRecursionBound(
             ((InstanceKeyWithNode) ik).getNode().getContext(), curLevel + 1)) {
           return true;
         }
       }
     }
   }
   return false;
 }
예제 #7
0
 @Test
 public void testSystemProperties()
     throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
   AnalysisScope scope =
       CallGraphTestUtil.makeJ2SEAnalysisScope(
           TestConstants.WALA_TESTDATA, CallGraphTestUtil.REGRESSION_EXCLUSIONS);
   ClassHierarchy cha = ClassHierarchy.make(scope);
   Iterable<Entrypoint> entrypoints =
       com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(
           scope, cha, "LstaticInit/TestSystemProperties");
   AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints);
   SSAPropagationCallGraphBuilder builder =
       Util.makeZeroCFABuilder(options, new AnalysisCache(), cha, scope);
   CallGraph cg = builder.makeCallGraph(options);
   for (CGNode n : cg) {
     if (n.toString()
         .equals(
             "Node: < Application, LstaticInit/TestSystemProperties, main([Ljava/lang/String;)V > Context: Everywhere")) {
       boolean foundToCharArray = false;
       for (CGNode callee : Iterator2Iterable.make(cg.getSuccNodes(n))) {
         if (callee.getMethod().getName().toString().equals("toCharArray")) {
           foundToCharArray = true;
           break;
         }
       }
       Assert.assertTrue(foundToCharArray);
       break;
     }
   }
 }
예제 #8
0
 public IR getIR(CGNode n) {
   // AnalysisOptions options = new AnalysisOptions();
   IR ir =
       analysisCache
           .getSSACache()
           .findOrCreateIR(n.getMethod(), n.getContext(), options.getSSAOptions());
   return ir;
 }
예제 #9
0
  @Override
  public IMethod getCalleeTarget(CGNode caller, CallSiteReference site, IClass receiver) {
    IMethod target = base.getCalleeTarget(caller, site, receiver);
    if (target != null && target.getReference().equals(loadFileFunRef)) {

      Set<String> names = new HashSet<String>();
      SSAInstruction call =
          caller.getIR()
              .getInstructions()[
              caller.getIR().getCallInstructionIndices(site).intIterator().next()];
      if (call.getNumberOfUses() > 1) {
        LocalPointerKey fileNameV = new LocalPointerKey(caller, call.getUse(1));
        OrdinalSet<InstanceKey> ptrs = builder.getPointerAnalysis().getPointsToSet(fileNameV);
        for (InstanceKey k : ptrs) {
          if (k instanceof ConstantKey) {
            Object v = ((ConstantKey) k).getValue();
            if (v instanceof String) {
              names.add((String) v);
            }
          }
        }

        if (names.size() == 1) {
          String str = names.iterator().next();
          try {
            JavaScriptLoader cl =
                (JavaScriptLoader) builder.getClassHierarchy().getLoader(JavaScriptTypes.jsLoader);
            URL url = new URL(builder.getBaseURL(), str);
            if (!loadedFiles.contains(url)) {
              // try to open the input stream for the URL.  if it fails, we'll get an IOException
              // and fall through to default case
              InputStream inputStream = url.openConnection().getInputStream();
              inputStream.close();
              JSCallGraphUtil.loadAdditionalFile(builder.getClassHierarchy(), cl, url);
              loadedFiles.add(url);
              IClass script =
                  builder
                      .getClassHierarchy()
                      .lookupClass(
                          TypeReference.findOrCreate(cl.getReference(), "L" + url.getFile()));
              return script.getMethod(JavaScriptMethods.fnSelector);
            }
          } catch (MalformedURLException e1) {
            // do nothing, fall through and return 'target'
          } catch (IOException e) {
            // do nothing, fall through and return 'target'
          } catch (RuntimeException e) {
            // do nothing, fall through and return 'target'
          }
        }
      }
    }

    return target;
  }
예제 #10
0
  @SuppressWarnings("unused")
  public void run() throws UnsoundGraphException {
    Set<CGNode> allCalled = findAllCalledMethods(cg.getEntrypointNodes());

    for (CGNode method : allCalled) {
      IMethod im = method.getMethod();
      if (!im.isNative() && !im.isAbstract() && !im.isSynthetic()) {
        ControlFlowGraph<SSAInstruction, IExplodedBasicBlock> cfg = getPruned(method, null);
      }
    }
  }
예제 #11
0
 /**
  * @see
  *     com.ibm.wala.ipa.callgraph.propagation.rta.RTAContextInterpreter#understands(com.ibm.wala.ipa.callgraph.CGNode)
  */
 @Override
 public boolean understands(CGNode node) {
   if (node == null) {
     throw new IllegalArgumentException("node is null");
   }
   if (!(node.getContext() instanceof GetMethodContext)) {
     return false;
   }
   MethodReference mRef = node.getMethod().getReference();
   return mRef.equals(GET_METHOD) || mRef.equals(GET_DECLARED_METHOD);
 }
예제 #12
0
  private FilteredPointerKey.TypeFilter getFilter(CGNode target) {
    FilteredPointerKey.TypeFilter filter =
        (FilteredPointerKey.TypeFilter) target.getContext().get(ContextKey.PARAMETERS[0]);

    if (filter != null) {
      return filter;
    } else {
      // the context does not select a particular concrete type for the
      // receiver.
      IClass C = getReceiverClass(target.getMethod());
      return new FilteredPointerKey.SingleClassFilter(C);
    }
  }
예제 #13
0
  private static void printDetails(CGNode method, ExplodedControlFlowGraph cfg, FlowGraph pruned) {
    int deletedEdges = 0;
    int originalEdges = 0;
    for (IExplodedBasicBlock node : cfg) {
      originalEdges += cfg.getSuccNodeCount(node);

      Iterator<IExplodedBasicBlock> it = cfg.getSuccNodes(node);

      int srcNum = node.getNumber();
      while (it.hasNext()) {
        IExplodedBasicBlock dst = it.next();
        int dstNum = dst.getNumber();
        if (pruned.hasEdge(srcNum, dstNum)) {
          deletedEdges++;
        }
      }
    }

    DecimalFormat df = new DecimalFormat("00.00");

    double percent = ((double) deletedEdges / (double) originalEdges) * 100.0;
    Log.info(
        "EXC: "
            + df.format(percent)
            + "% - edges: "
            + originalEdges
            + " deleted: "
            + deletedEdges
            + " - "
            + edu.kit.joana.deprecated.jsdg.util.Util.methodName(method.getMethod()));
  }
예제 #14
0
 @Override
 public PointerKey getPointerKeyForLocal(CGNode node, int valueNumber) {
   if (!node.getMethod().isStatic() && valueNumber == 1) {
     return delegate.getFilteredPointerKeyForLocal(node, valueNumber, getFilter(node));
   } else {
     return delegate.getPointerKeyForLocal(node, valueNumber);
   }
 }
  /**
   * Add constraints to represent the flow of exceptions to the exceptional return value for this
   * node
   */
  protected void addNodePassthruExceptionConstraints(CGNode node, IR ir) {
    // add constraints relating to thrown exceptions that reach the exit block.
    List<ProgramCounter> peis =
        SSAPropagationCallGraphBuilder.getIncomingPEIs(ir, ir.getExitBlock());
    PointerKey exception = heapModel.getPointerKeyForExceptionalReturnValue(node);
    IClass c = node.getClassHierarchy().lookupClass(TypeReference.JavaLangThrowable);

    addExceptionDefConstraints(ir, node, peis, exception, Collections.singleton(c));
  }
예제 #16
0
  public void addNonEntryReportData(
      final String sourceFilePath, final Set<Integer> lines, final CGNode cgNode) {
    JavaFileData dataForNode = reportData.getJavaFileDataForCGNode(cgNode);
    if (dataForNode == null) {
      dataForNode =
          reportData.addNewJavaFileData(sourceFilePath, cgNode.getMethod().getDeclaringClass());
    }

    dataForNode.addLineNumbersForCGNode(cgNode, lines);
  }
 @Override
 public IMethod getCalleeTarget(CGNode caller, CallSiteReference site, IClass receiver) {
   if (site.getDeclaredTarget().equals(JavaScriptMethods.ctorReference)) {
     assert cha.isSubclassOf(receiver, cha.lookupClass(JavaScriptTypes.Root));
     IR callerIR = caller.getIR();
     SSAAbstractInvokeInstruction callStmts[] = callerIR.getCalls(site);
     assert callStmts.length == 1;
     int nargs = callStmts[0].getNumberOfParameters();
     return findOrCreateConstructorMethod(callerIR, callStmts[0], receiver, nargs - 1);
   } else {
     return base.getCalleeTarget(caller, site, receiver);
   }
 }
예제 #18
0
 @Override
 public Iterator<NewSiteReference> iterateNewSites(CGNode node) {
   if (node == null) {
     throw new IllegalArgumentException("node is null");
   }
   assert understands(node);
   GetMethodContext context = (GetMethodContext) node.getContext();
   TypeReference tr = context.getType().getTypeReference();
   if (tr != null) {
     return new NonNullSingletonIterator<NewSiteReference>(NewSiteReference.make(0, tr));
   }
   return EmptyIterator.instance();
 }
예제 #19
0
  /* (non-Javadoc)
   * @see edu.kit.ipd.wala.ExceptionPrunedCFG#getPruned(com.ibm.wala.ipa.callgraph.CGNode)
   */
  @Override
  public ControlFlowGraph<SSAInstruction, IExplodedBasicBlock> getPruned(
      CGNode method, IProgressMonitor progress) throws UnsoundGraphException {
    FlowGraph graph = cg2graph.get(method);
    ExplodedControlFlowGraph origCfg = cg2origcfg.get(method);

    if (graph == null) {
      if (DEBUG) {
        String fileName = method.getMethod().getSignature();
        fileName = fileName.replace('/', '.');
        System.out.println("--- Starting " + fileName + " ---");

        MethodCFG mCFG = new MethodCFG(method, ignoreExceptions);
        if (mCFG.init(cache)) {
          mCFG.write(mCFG.getOriginalGraph(), "out/" + fileName + ".dot");
          System.out.println(
              "Exceptions in original graph: " + mCFG.getOriginalGraph().countExceptions());

          mCFG.purgeExceptions();

          graph = mCFG.getGraph();
          mCFG.write(graph, "out/" + fileName + ".filter.dot");
          System.out.println("Exceptions in final graph: " + graph.countExceptions());

          cg2graph.put(method, graph);
          origCfg = mCFG.getECFG();
          cg2origcfg.put(method, origCfg);
        }
      } else {
        MethodCFG mCFG = new MethodCFG(method, ignoreExceptions);
        if (mCFG.init(cache)) {
          mCFG.purgeExceptions();
          graph = mCFG.getGraph();
          cg2graph.put(method, graph);
          origCfg = mCFG.getECFG();
          cg2origcfg.put(method, origCfg);
        }
      }

      printDetails(method, origCfg, graph);
    }

    if (graph != null) {
      IgnoreEdgeListFilter filter = new IgnoreEdgeListFilter(origCfg, graph);
      PrunedCFG<SSAInstruction, IExplodedBasicBlock> pCFG = PrunedCFG.make(origCfg, filter);

      return pCFG;
    } else {
      return null;
    }
  }
예제 #20
0
파일: Analyzer.java 프로젝트: BoAnd/tools
  public void start(Class<? extends ICostComputer<ICostResult>> costComputerType)
      throws InstantiationException, IllegalAccessException, IllegalArgumentException,
          WalaException, IOException, SecurityException, InvocationTargetException,
          NoSuchMethodException {
    this.costComputer =
        costComputerType
            .getDeclaredConstructor(JVMModel.class)
            .newInstance(specification.getJvmModel());

    LinkedList<CGNode> entryCGNodes = specification.getEntryPointCGNodes();

    for (CGNode entryNode : entryCGNodes) {
      // OutputPrinter.printInfo("Starting entry node " + entryNode.getMethod().toString());
      ICostResult results = new CGNodeAnalyzer(entryNode, costComputer).analyzeNode();
      // ICostResult results = new
      // CostComputerMemory(specification.getJvmModel()).dfsVisit(entryNode);
      // Test code
      CostResultMemory memRes = (CostResultMemory) results;
      OutputPrinter.printInfo(
          "Worst case allocation for "
              + entryNode.getMethod().toString()
              + ":\t"
              + results.getCostScalar());
      for (Entry<TypeName, Integer> i : memRes.aggregatedCountByTypename.entrySet()) {
        OutputPrinter.printInfo(
            "\t TYPE_NAME\t" + i.getKey().toString() + "\tCOUNT " + i.getValue());
      }
    }
    /* This is move to the program.
    if ( specification.getTypeOfAnalysisPerformed() != AnalysisType.ALLOCATIONS) {
    	stackAnalyzer.analyze();
    }

    if ( specification.getShouldGenerateAnalysisReports() == true) {
    	ReportGenerator gen = new ReportGenerator();
    	gen.Generate(AnalysisResults.getAnalysisResults().getReportEntries());
    }*/
  }
예제 #21
0
 /**
  * @see
  *     com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter#getIR(com.ibm.wala.ipa.callgraph.CGNode)
  */
 @Override
 public IR getIR(CGNode node) {
   if (node == null) {
     throw new IllegalArgumentException("node is null");
   }
   assert understands(node);
   if (DEBUG) {
     System.err.println("generating IR for " + node);
   }
   IMethod method = node.getMethod();
   GetMethodContext context = (GetMethodContext) node.getContext();
   Map<Integer, ConstantValue> constants = HashMapFactory.make();
   if (method.getReference().equals(GET_METHOD)) {
     Atom name = Atom.findOrCreateAsciiAtom(context.getName());
     SSAInstruction instrs[] = makeGetMethodStatements(context, constants, name);
     return new SyntheticIR(
         method,
         context,
         new InducedCFG(instrs, method, context),
         instrs,
         SSAOptions.defaultOptions(),
         constants);
   }
   if (method.getReference().equals(GET_DECLARED_METHOD)) {
     Atom name = Atom.findOrCreateAsciiAtom(context.getName());
     SSAInstruction instrs[] = makeGetDeclaredMethodStatements(context, constants, name);
     return new SyntheticIR(
         method,
         context,
         new InducedCFG(instrs, method, context),
         instrs,
         SSAOptions.defaultOptions(),
         constants);
   }
   Assertions.UNREACHABLE("Unexpected method " + node);
   return null;
 }
예제 #22
0
 /**
  * Compute the set of PointerKeys each statement refs.Be careful to avoid eager PDG construction
  * here! That means .. don't iterate over SDG statements!
  */
 public static Map<Statement, Set<PointerKey>> scanForRef(
     SDG sdg, PointerAnalysis pa, ModRef modRef) {
   if (pa == null) {
     throw new IllegalArgumentException("null pa");
   }
   ExtendedHeapModel h = new DelegatingExtendedHeapModel(pa.getHeapModel());
   Map<Statement, Set<PointerKey>> result = HashMapFactory.make();
   for (CGNode n : sdg.getCallGraph()) {
     IR ir = n.getIR();
     if (ir != null) {
       for (int i = 0; i < ir.getInstructions().length; i++) {
         SSAInstruction st = ir.getInstructions()[i];
         if (st != null) {
           Set<PointerKey> mod = modRef.getRef(n, h, pa, st, null);
           if (!mod.isEmpty()) {
             NormalStatement normal = new NormalStatement(n, i);
             result.put(normal, mod);
           }
         }
       }
     }
   }
   return result;
 }
 @Override
 public Context getCalleeTarget(
     CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] actualParameters) {
   Context baseContext = base.getCalleeTarget(caller, site, callee, actualParameters);
   final boolean exceedsRecursionBound = exceedsRecursionBound(baseContext, 0);
   if (!exceedsRecursionBound) {
     return baseContext;
   } else if (callee instanceof JavaScriptConstructor) {
     // for constructors, we want to keep some basic context sensitivity to
     // avoid horrible imprecision
     return new CallStringContext(new CallString(site, caller.getMethod()));
   } else {
     // TODO somehow k-limit more smartly?
     return Everywhere.EVERYWHERE;
   }
 }
 /**
  * add nodes for parameters and return values
  *
  * @param node
  */
 private void addNodesForParameters(CGNode node) {
   // TODO Auto-generated method stub
   IR ir = node.getIR();
   TypeInference ti = TypeInference.make(ir, false);
   SymbolTable symbolTable = ir.getSymbolTable();
   for (int i = 0; i < symbolTable.getNumberOfParameters(); i++) {
     int parameter = symbolTable.getParameter(i);
     TypeAbstraction t = ti.getType(parameter);
     if (t != null) {
       PointerKey paramPk = heapModel.getPointerKeyForLocal(node, parameter);
       addNode(paramPk);
       params.put(paramPk, node);
     }
   }
   addNode(heapModel.getPointerKeyForReturnValue(node));
   addNode(heapModel.getPointerKeyForExceptionalReturnValue(node));
 }
예제 #25
0
  private static List<Pair<CGNode, SSACheckCastInstruction>> findFailingCasts(
      CallGraph cg, DemandRefinementPointsTo dmp) {
    final IClassHierarchy cha = dmp.getClassHierarchy();
    List<Pair<CGNode, SSACheckCastInstruction>> failing =
        new ArrayList<Pair<CGNode, SSACheckCastInstruction>>();

    int numSafe = 0, numMightFail = 0;
    outer:
    for (Iterator<? extends CGNode> nodeIter = cg.iterator(); nodeIter.hasNext(); ) {
      CGNode node = nodeIter.next();
      TypeReference declaringClass = node.getMethod().getReference().getDeclaringClass();
      // skip library classes
      if (declaringClass.getClassLoader().equals(ClassLoaderReference.Primordial)) {
        continue;
      }
      IR ir = node.getIR();
      if (ir == null) continue;
      SSAInstruction[] instrs = ir.getInstructions();
      for (int i = 0; i < instrs.length; i++) {
        if (numSafe + numMightFail > MAX_CASTS) break outer;
        SSAInstruction instruction = instrs[i];
        if (instruction instanceof SSACheckCastInstruction) {
          SSACheckCastInstruction castInstr = (SSACheckCastInstruction) instruction;
          final TypeReference[] declaredResultTypes = castInstr.getDeclaredResultTypes();

          boolean primOnly = true;
          for (TypeReference t : declaredResultTypes) {
            if (!t.isPrimitiveType()) {
              primOnly = false;
            }
          }
          if (primOnly) {
            continue;
          }

          System.err.println("CHECKING " + castInstr + " in " + node.getMethod());
          PointerKey castedPk = heapModel.getPointerKeyForLocal(node, castInstr.getUse(0));
          Predicate<InstanceKey> castPred =
              new Predicate<InstanceKey>() {

                @Override
                public boolean test(InstanceKey ik) {
                  TypeReference ikTypeRef = ik.getConcreteType().getReference();
                  for (TypeReference t : declaredResultTypes) {
                    if (cha.isAssignableFrom(cha.lookupClass(t), cha.lookupClass(ikTypeRef))) {
                      return true;
                    }
                  }
                  return false;
                }
              };
          long startTime = System.currentTimeMillis();
          Pair<PointsToResult, Collection<InstanceKey>> queryResult =
              dmp.getPointsTo(castedPk, castPred);
          long runningTime = System.currentTimeMillis() - startTime;
          System.err.println("running time: " + runningTime + "ms");
          final FieldRefinePolicy fieldRefinePolicy =
              dmp.getRefinementPolicy().getFieldRefinePolicy();
          switch (queryResult.fst) {
            case SUCCESS:
              System.err.println("SAFE: " + castInstr + " in " + node.getMethod());
              if (fieldRefinePolicy instanceof ManualFieldPolicy) {
                ManualFieldPolicy hackedFieldPolicy = (ManualFieldPolicy) fieldRefinePolicy;
                System.err.println(hackedFieldPolicy.getHistory());
              }
              System.err.println("TRAVERSED " + dmp.getNumNodesTraversed() + " nodes");
              numSafe++;
              break;
            case NOMOREREFINE:
              if (queryResult.snd != null) {
                System.err.println(
                    "MIGHT FAIL: no more refinement possible for "
                        + castInstr
                        + " in "
                        + node.getMethod());
              } else {
                System.err.println(
                    "MIGHT FAIL: exceeded budget for " + castInstr + " in " + node.getMethod());
              }
              failing.add(Pair.make(node, castInstr));
              numMightFail++;
              break;
            case BUDGETEXCEEDED:
              System.err.println(
                  "MIGHT FAIL: exceeded budget for " + castInstr + " in " + node.getMethod());
              failing.add(Pair.make(node, castInstr));
              numMightFail++;
              break;
            default:
              Assertions.UNREACHABLE();
          }
        }
      }
      // break outer;
    }
    System.err.println("TOTAL SAFE: " + numSafe);
    System.err.println("TOTAL MIGHT FAIL: " + numMightFail);
    return failing;
  }