org.apache.bcel.generic.CodeExceptionGen Java Examples

The following examples show how to use org.apache.bcel.generic.CodeExceptionGen. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ExceptionHandlerMap.java    From spotbugs with GNU Lesser General Public License v2.1 6 votes vote down vote up
public static CodeExceptionGen merge(@CheckForNull TypeMerger m, CodeExceptionGen e1, CodeExceptionGen e2) {
    if (e1 == null) {
        return e2;
    }
    if (e2 == null) {
        return e1;
    }
    if (m == null) {
        return e1;
    }
    if (!e1.getHandlerPC().equals(e2.getHandlerPC())) {
        // log error
        return e1;
    }
    try {
        Type t = m.mergeTypes(e1.getCatchType(), e2.getCatchType());
        return new CodeExceptionGen(e1.getStartPC(), e1.getEndPC(), e1.getHandlerPC(), (ObjectType) t);
    } catch (DataflowAnalysisException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return e1;
    }
}
 
Example #2
Source File: BetterCFGBuilder2.java    From spotbugs with GNU Lesser General Public License v2.1 6 votes vote down vote up
/**
 * Get the basic block in the subroutine for the given instruction. If
 * the block doesn't exist yet, it is created, and a work list item is
 * added which will populate it. Note that if start is an exception
 * thrower, the block returned will be its ETB.
 *
 * @param start
 *            the start instruction for the block
 * @return the basic block for the instruction
 */
public BasicBlock getBlock(InstructionHandle start) {
    BasicBlock block = blockMap.get(start);
    if (block == null) {
        block = allocateBasicBlock();
        blockMap.put(start, block);

        // Block is an exception handler?
        CodeExceptionGen exceptionGen = exceptionHandlerMap.getHandlerForStartInstruction(start);
        if (exceptionGen != null) {
            block.setExceptionGen(null, exceptionGen);
        }

        addItem(new WorkListItem(start, block));
    }
    return block;
}
 
Example #3
Source File: BlockTypeAnalysis.java    From spotbugs with GNU Lesser General Public License v2.1 6 votes vote down vote up
@Override
public void transfer(BasicBlock basicBlock, @CheckForNull InstructionHandle end, BlockType start, BlockType result)
        throws DataflowAnalysisException {
    result.copyFrom(start);

    if (start.isValid() && basicBlock.isExceptionHandler()) {
        CodeExceptionGen exceptionGen = basicBlock.getExceptionGen();
        ObjectType catchType = exceptionGen.getCatchType();
        if (catchType == null) {
            // Probably a finally block, or a synchronized block
            // exception-compensation catch block.
            result.pushFinally();
        } else {
            // Catch type was explicitly specified:
            // this is probably a programmer-written catch block
            result.pushCatch();
        }
    }
}
 
Example #4
Source File: ExceptionHandlers.java    From commons-bcel with Apache License 2.0 6 votes vote down vote up
/**
 * Constructor. Creates a new ExceptionHandlers instance.
 */
public ExceptionHandlers(final MethodGen mg) {
    exceptionHandlers = new HashMap<>();
    final CodeExceptionGen[] cegs = mg.getExceptionHandlers();
    for (final CodeExceptionGen ceg : cegs) {
        final ExceptionHandler eh = new ExceptionHandler(ceg.getCatchType(), ceg.getHandlerPC());
        for (InstructionHandle ih=ceg.getStartPC(); ih != ceg.getEndPC().getNext(); ih=ih.getNext()) {
            Set<ExceptionHandler> hs;
            hs = exceptionHandlers.get(ih);
            if (hs == null) {
                hs = new HashSet<>();
                exceptionHandlers.put(ih, hs);
            }
            hs.add(eh);
        }
    }
}
 
Example #5
Source File: CFGPrinter.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
public void print(PrintStream out) {
    Iterator<BasicBlock> i = cfg.blockIterator();
    while (i.hasNext()) {
        BasicBlock bb = i.next();
        out.println();
        out.println("BASIC BLOCK: " + bb.getLabel() + (bb.isExceptionThrower() ? " [EXCEPTION THROWER]" : "")
                + blockStartAnnotate(bb));
        if (bb.isExceptionThrower()) {
            out.println("  Exception thrower: " + bb.getExceptionThrower());
        }
        CodeExceptionGen exceptionGen = bb.getExceptionGen();
        if (exceptionGen != null) {
            out.println("\tCATCHES " + exceptionGen.getCatchType());
        }
        Iterator<InstructionHandle> j = instructionIterator(bb);
        while (j.hasNext()) {
            InstructionHandle handle = j.next();
            out.println(handle + instructionAnnotate(handle, bb));
        }
        out.println("END" + blockAnnotate(bb));
        Iterator<Edge> edgeIter = isForwards ? cfg.outgoingEdgeIterator(bb) : cfg.incomingEdgeIterator(bb);
        while (edgeIter.hasNext()) {
            Edge edge = edgeIter.next();
            out.println("  " + edge.formatAsString(!isForwards) + " " + edgeAnnotate(edge));
        }
    }
}
 
Example #6
Source File: ExceptionHandlerMap.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
private void addExceptionHandler(CodeExceptionGen exceptionHandler) {
    InstructionHandle handlerPC = exceptionHandler.getHandlerPC();
    CodeExceptionGen existing = startInstructionToHandlerMap.get(handlerPC);
    if (existing != null) {
        exceptionHandler = merge(this.merger, existing, exceptionHandler);
    }
    startInstructionToHandlerMap.put(handlerPC, exceptionHandler);
}
 
Example #7
Source File: BasicBlock.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Set the CodeExceptionGen object. Marks this basic block as the entry
 * point of an exception handler.
 *
 * @param exceptionGen
 *            the CodeExceptionGen object for the block
 */
public void setExceptionGen(@Nullable TypeMerger m, CodeExceptionGen exceptionGen) {
    if (this.exceptionGen != null) {
        AnalysisContext.logError("Multiple exception handlers");
    }

    this.exceptionGen = exceptionGen;
}
 
Example #8
Source File: BetterCFGBuilder2.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Add exception edges for given instruction.
 *
 * @param subroutine
 *            the subroutine containing the instruction
 * @param pei
 *            the instruction which throws an exception
 * @param etb
 *            the exception thrower block (ETB) for the instruction
 */
private void handleExceptions(Subroutine subroutine, InstructionHandle pei, BasicBlock etb) {
    etb.setExceptionThrower(pei);

    // Remember whether or not a universal exception handler
    // is reachable. If so, then we know that exceptions raised
    // at this instruction cannot propagate out of the method.
    boolean sawUniversalExceptionHandler = false;

    List<CodeExceptionGen> exceptionHandlerList = exceptionHandlerMap.getHandlerList(pei);
    if (exceptionHandlerList != null) {
        for (CodeExceptionGen exceptionHandler : exceptionHandlerList) {
            InstructionHandle handlerStart = exceptionHandler.getHandlerPC();
            subroutine.addEdgeAndExplore(etb, handlerStart, HANDLED_EXCEPTION_EDGE);

            if (Hierarchy.isUniversalExceptionHandler(exceptionHandler.getCatchType())) {
                sawUniversalExceptionHandler = true;
            }
        }
    }

    // If required, mark this block as throwing an unhandled exception.
    // For now, we assume that if there is no reachable handler that handles
    // ANY exception type, then the exception can be thrown out of the
    // method.
    if (!sawUniversalExceptionHandler) {
        if (DEBUG) {
            System.out.println("Adding unhandled exception edge from " + pei);
        }
        subroutine.setUnhandledExceptionBlock(etb);
    }
}
 
Example #9
Source File: BCELFactory.java    From commons-bcel with Apache License 2.0 5 votes vote down vote up
private void updateExceptionHandlers() {
    final CodeExceptionGen[] handlers = _mg.getExceptionHandlers();
    for (final CodeExceptionGen h : handlers) {
        final String type = (h.getCatchType() == null) ? "null" : BCELifier.printType(h
                .getCatchType());
        _out.println("    method.addExceptionHandler(" + "ih_" + h.getStartPC().getPosition()
                + ", " + "ih_" + h.getEndPC().getPosition() + ", " + "ih_"
                + h.getHandlerPC().getPosition() + ", " + type + ");");
    }
}
 
Example #10
Source File: ExceptionHandlerMap.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
private void addHandler(InstructionHandle handle, CodeExceptionGen exceptionHandler) {
    List<CodeExceptionGen> handlerList = codeToHandlerMap.computeIfAbsent(handle, k -> new LinkedList<>());
    handlerList.add(exceptionHandler);
}
 
Example #11
Source File: TypeAnalysis.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public void meetInto(TypeFrame fact, Edge edge, TypeFrame result) throws DataflowAnalysisException {
    BasicBlock basicBlock = edge.getTarget();

    if (fact.isValid()) {
        TypeFrame tmpFact = null;

        // Handling an exception?
        if (basicBlock.isExceptionHandler()) {
            tmpFact = modifyFrame(fact, null);

            // Special case: when merging predecessor facts for entry to
            // an exception handler, we clear the stack and push a
            // single entry for the exception object. That way, the locals
            // can still be merged.
            CodeExceptionGen exceptionGen = basicBlock.getExceptionGen();
            tmpFact.clearStack();

            // Determine the type of exception(s) caught.
            Type catchType = null;

            if (FORCE_ACCURATE_EXCEPTIONS
                    || AnalysisContext.currentAnalysisContext().getBoolProperty(AnalysisFeatures.ACCURATE_EXCEPTIONS)) {
                try {
                    // Ideally, the exceptions that can be propagated
                    // on this edge has already been computed.
                    CachedExceptionSet cachedExceptionSet = getCachedExceptionSet(edge.getSource());
                    ExceptionSet edgeExceptionSet = cachedExceptionSet.getEdgeExceptionSet(edge);
                    if (!edgeExceptionSet.isEmpty()) {
                        // System.out.println("Using computed edge exception set!");
                        catchType = ExceptionObjectType.fromExceptionSet(edgeExceptionSet);
                    }
                } catch (ClassNotFoundException e) {
                    lookupFailureCallback.reportMissingClass(e);
                }
            }

            if (catchType == null) {
                // No information about propagated exceptions, so
                // pick a type conservatively using the handler catch type.
                catchType = exceptionGen.getCatchType();
                if (catchType == null) {
                    catchType = Type.THROWABLE; // handle catches anything
                    // throwable
                }
            }

            tmpFact.pushValue(catchType);
        }

        // See if we can make some types more precise due to
        // a successful instanceof check in the source block.
        if (valueNumberDataflow != null) {
            tmpFact = handleInstanceOfBranch(fact, tmpFact, edge);
        }

        if (tmpFact != null) {
            fact = tmpFact;
        }
    }

    mergeInto(fact, result);
}
 
Example #12
Source File: TypeAnalysis.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Based on the set of exceptions that can be thrown from the source basic
 * block, compute the set of exceptions that can propagate along given
 * exception edge. This method should be called for each outgoing exception
 * edge in sequence, so the caught exceptions can be removed from the thrown
 * exception set as needed.
 *
 * @param edge
 *            the exception edge
 * @param thrownExceptionSet
 *            current set of exceptions that can be thrown, taking earlier
 *            (higher priority) exception edges into account
 * @return the set of exceptions that can propagate along this edge
 */
private ExceptionSet computeEdgeExceptionSet(Edge edge, ExceptionSet thrownExceptionSet) {

    if (thrownExceptionSet.isEmpty()) {
        return thrownExceptionSet;
    }
    ExceptionSet result = exceptionSetFactory.createExceptionSet();

    if (edge.getType() == UNHANDLED_EXCEPTION_EDGE) {
        // The unhandled exception edge always comes
        // after all of the handled exception edges.
        result.addAll(thrownExceptionSet);
        thrownExceptionSet.clear();
        return result;
    }

    BasicBlock handlerBlock = edge.getTarget();
    CodeExceptionGen handler = handlerBlock.getExceptionGen();
    ObjectType catchType = handler.getCatchType();

    if (Hierarchy.isUniversalExceptionHandler(catchType)) {
        result.addAll(thrownExceptionSet);
        thrownExceptionSet.clear();
    } else {
        // Go through the set of thrown exceptions.
        // Any that will DEFINITELY be caught be this handler, remove.
        // Any that MIGHT be caught, but won't definitely be caught,
        // remain.

        for (ExceptionSet.ThrownExceptionIterator i = thrownExceptionSet.iterator(); i.hasNext();) {
            // ThrownException thrownException = i.next();
            ObjectType thrownType = i.next();
            boolean explicit = i.isExplicit();

            if (DEBUG) {
                System.out.println("\texception type " + thrownType + ", catch type " + catchType);
            }

            try {
                if (Hierarchy.isSubtype(thrownType, catchType)) {
                    // Exception can be thrown along this edge
                    result.add(thrownType, explicit);

                    // And it will definitely be caught
                    i.remove();

                    if (DEBUG) {
                        System.out.println("\tException is subtype of catch type: " + "will definitely catch");
                    }
                } else if (Hierarchy.isSubtype(catchType, thrownType)) {
                    // Exception possibly thrown along this edge
                    result.add(thrownType, explicit);

                    if (DEBUG) {
                        System.out.println("\tException is supertype of catch type: " + "might catch");
                    }
                }
            } catch (ClassNotFoundException e) {
                // As a special case, if a class hierarchy lookup
                // fails, then we will conservatively assume that the
                // exception in question CAN, but WON'T NECESSARILY
                // be caught by the handler.
                AnalysisContext.reportMissingClass(e);
                result.add(thrownType, explicit);
            }
        }
    }

    return result;
}
 
Example #13
Source File: ExceptionHandlerMap.java    From spotbugs with GNU Lesser General Public License v2.1 2 votes vote down vote up
/**
 * Get the list of exception handlers (CodeExceptionGen objects) which are
 * specified to handle exceptions for the instruction whose handle is given.
 * Note that the handlers in the returned list are <b>in order of
 * priority</b>, as defined in the method's exception handler table.
 *
 * @param handle
 *            the handle of the instruction we want the exception handlers
 *            for
 * @return the list of exception handlers, or null if there are no handlers
 *         registered for the instruction
 */
public List<CodeExceptionGen> getHandlerList(InstructionHandle handle) {
    return codeToHandlerMap.get(handle);
}
 
Example #14
Source File: ExceptionHandlerMap.java    From spotbugs with GNU Lesser General Public License v2.1 2 votes vote down vote up
/**
 * If the given instruction is the start of an exception handler, get the
 * CodeExceptionGen object representing the handler.
 *
 * @param start
 *            the instruction
 * @return the CodeExceptionGen object, or null if the instruction is not
 *         the start of an exception handler
 */
public CodeExceptionGen getHandlerForStartInstruction(InstructionHandle start) {
    return startInstructionToHandlerMap.get(start);
}
 
Example #15
Source File: BasicBlock.java    From spotbugs with GNU Lesser General Public License v2.1 2 votes vote down vote up
/**
 * Get CodeExceptionGen object; returns null if this basic block is not the
 * entry point of an exception handler.
 *
 * @return the CodeExceptionGen object, or null
 */
public CodeExceptionGen getExceptionGen() {
    return exceptionGen;
}