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)); } } }