Exemplo n.º 1
0
  public AbstractBlockOrder(CFG cfg, Comparator<BasicBlock> comparator) {
    this.comparator = comparator;
    // Put the blocks in an array
    int numBlocks = cfg.getNumBasicBlocks(), count = 0;
    BasicBlock[] blocks = new BasicBlock[numBlocks];
    for (Iterator<BasicBlock> i = cfg.blockIterator(); i.hasNext(); ) {
      blocks[count++] = i.next();
    }
    assert count == numBlocks;

    // Sort the blocks according to the comparator
    Arrays.sort(blocks, comparator);

    // Put the ordered blocks into an array list
    blockList = new ArrayList<BasicBlock>(numBlocks);
    for (int i = 0; i < numBlocks; ++i) blockList.add(blocks[i]);
  }
  private void analyzeMethod(ClassContext classContext, Method method)
      throws CFGBuilderException, DataflowAnalysisException {
    if (BCELUtil.isSynthetic(method)
        || (method.getAccessFlags() & Const.ACC_BRIDGE) == Const.ACC_BRIDGE) {
      return;
    }
    CFG cfg = classContext.getCFG(method);

    ConstantPoolGen cpg = classContext.getConstantPoolGen();
    TypeDataflow typeDataflow = classContext.getTypeDataflow(method);

    for (Iterator<BasicBlock> i = cfg.blockIterator(); i.hasNext(); ) {
      BasicBlock basicBlock = i.next();

      // Check if it's a method invocation.
      if (!basicBlock.isExceptionThrower()) {
        continue;
      }
      InstructionHandle thrower = basicBlock.getExceptionThrower();
      Instruction ins = thrower.getInstruction();
      if (!(ins instanceof InvokeInstruction)) {
        continue;
      }

      InvokeInstruction inv = (InvokeInstruction) ins;
      boolean foundThrower = false;
      boolean foundNonThrower = false;

      if (inv instanceof INVOKEINTERFACE) {
        continue;
      }

      String className = inv.getClassName(cpg);

      Location loc = new Location(thrower, basicBlock);
      TypeFrame typeFrame = typeDataflow.getFactAtLocation(loc);
      XMethod primaryXMethod = XFactory.createXMethod(inv, cpg);
      // if (primaryXMethod.isAbstract()) continue;
      Set<XMethod> targetSet = null;
      try {

        if (className.startsWith("[")) {
          continue;
        }
        String methodSig = inv.getSignature(cpg);
        if (!methodSig.endsWith("V")) {
          continue;
        }

        targetSet = Hierarchy2.resolveMethodCallTargets(inv, typeFrame, cpg);

        for (XMethod xMethod : targetSet) {
          if (DEBUG) {
            System.out.println("\tFound " + xMethod);
          }

          boolean isUnconditionalThrower =
              xMethod.isUnconditionalThrower()
                  && !xMethod.isUnsupported()
                  && !xMethod.isSynthetic();
          if (isUnconditionalThrower) {
            foundThrower = true;
            if (DEBUG) {
              System.out.println("Found thrower");
            }
          } else {
            foundNonThrower = true;
            if (DEBUG) {
              System.out.println("Found non thrower");
            }
          }
        }
      } catch (ClassNotFoundException e) {
        analysisContext.getLookupFailureCallback().reportMissingClass(e);
      }
      boolean newResult = foundThrower && !foundNonThrower;
      if (newResult) {
        bugReporter.reportBug(
            new BugInstance(this, "TESTING", Priorities.NORMAL_PRIORITY)
                .addClassAndMethod(classContext.getJavaClass(), method)
                .addString("Call to method that always throws Exception")
                .addMethod(primaryXMethod)
                .describe(MethodAnnotation.METHOD_CALLED)
                .addSourceLine(classContext, method, loc));
      }
    }
  }