Search in sources :

Example 11 with ExceptionBlock

use of org.checkerframework.dataflow.cfg.block.ExceptionBlock in project bazel by bazelbuild.

the class Analysis method performAnalysis.

/**
     * Perform the actual analysis. Should only be called once after the object
     * has been created.
     *
     * @param cfg
     */
public void performAnalysis(ControlFlowGraph cfg) {
    assert isRunning == false;
    isRunning = true;
    init(cfg);
    while (!worklist.isEmpty()) {
        Block b = worklist.poll();
        switch(b.getType()) {
            case REGULAR_BLOCK:
                {
                    RegularBlock rb = (RegularBlock) b;
                    // apply transfer function to contents
                    TransferInput<A, S> inputBefore = getInputBefore(rb);
                    currentInput = inputBefore.copy();
                    TransferResult<A, S> transferResult = null;
                    Node lastNode = null;
                    boolean addToWorklistAgain = false;
                    for (Node n : rb.getContents()) {
                        transferResult = callTransferFunction(n, currentInput);
                        addToWorklistAgain |= updateNodeValues(n, transferResult);
                        currentInput = new TransferInput<>(n, this, transferResult);
                        lastNode = n;
                    }
                    // loop will run at least one, making transferResult non-null
                    // propagate store to successors
                    Block succ = rb.getSuccessor();
                    assert succ != null : "regular basic block without non-exceptional successor unexpected";
                    propagateStoresTo(succ, lastNode, currentInput, rb.getFlowRule(), addToWorklistAgain);
                    break;
                }
            case EXCEPTION_BLOCK:
                {
                    ExceptionBlock eb = (ExceptionBlock) b;
                    // apply transfer function to content
                    TransferInput<A, S> inputBefore = getInputBefore(eb);
                    currentInput = inputBefore.copy();
                    Node node = eb.getNode();
                    TransferResult<A, S> transferResult = callTransferFunction(node, currentInput);
                    boolean addToWorklistAgain = updateNodeValues(node, transferResult);
                    // propagate store to successor
                    Block succ = eb.getSuccessor();
                    if (succ != null) {
                        currentInput = new TransferInput<>(node, this, transferResult);
                        // TODO? Variable wasn't used.
                        // Store.FlowRule storeFlow = eb.getFlowRule();
                        propagateStoresTo(succ, node, currentInput, eb.getFlowRule(), addToWorklistAgain);
                    }
                    // propagate store to exceptional successors
                    for (Entry<TypeMirror, Set<Block>> e : eb.getExceptionalSuccessors().entrySet()) {
                        TypeMirror cause = e.getKey();
                        S exceptionalStore = transferResult.getExceptionalStore(cause);
                        if (exceptionalStore != null) {
                            for (Block exceptionSucc : e.getValue()) {
                                addStoreBefore(exceptionSucc, node, exceptionalStore, Store.Kind.BOTH, addToWorklistAgain);
                            }
                        } else {
                            for (Block exceptionSucc : e.getValue()) {
                                addStoreBefore(exceptionSucc, node, inputBefore.copy().getRegularStore(), Store.Kind.BOTH, addToWorklistAgain);
                            }
                        }
                    }
                    break;
                }
            case CONDITIONAL_BLOCK:
                {
                    ConditionalBlock cb = (ConditionalBlock) b;
                    // get store before
                    TransferInput<A, S> inputBefore = getInputBefore(cb);
                    TransferInput<A, S> input = inputBefore.copy();
                    // propagate store to successor
                    Block thenSucc = cb.getThenSuccessor();
                    Block elseSucc = cb.getElseSuccessor();
                    propagateStoresTo(thenSucc, null, input, cb.getThenFlowRule(), false);
                    propagateStoresTo(elseSucc, null, input, cb.getElseFlowRule(), false);
                    break;
                }
            case SPECIAL_BLOCK:
                {
                    // special basic blocks are empty and cannot throw exceptions,
                    // thus there is no need to perform any analysis.
                    SpecialBlock sb = (SpecialBlock) b;
                    Block succ = sb.getSuccessor();
                    if (succ != null) {
                        propagateStoresTo(succ, null, getInputBefore(b), sb.getFlowRule(), false);
                    }
                    break;
                }
            default:
                assert false;
                break;
        }
    }
    assert isRunning == true;
    isRunning = false;
}
Also used : ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) Entry(java.util.Map.Entry) TypeMirror(javax.lang.model.type.TypeMirror) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) Node(org.checkerframework.dataflow.cfg.node.Node) ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) SpecialBlock(org.checkerframework.dataflow.cfg.block.SpecialBlock) Block(org.checkerframework.dataflow.cfg.block.Block) RegularBlock(org.checkerframework.dataflow.cfg.block.RegularBlock) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) SpecialBlock(org.checkerframework.dataflow.cfg.block.SpecialBlock) RegularBlock(org.checkerframework.dataflow.cfg.block.RegularBlock)

Example 12 with ExceptionBlock

use of org.checkerframework.dataflow.cfg.block.ExceptionBlock in project bazel by bazelbuild.

the class AnalysisResult method runAnalysisFor.

/**
     * Runs the analysis again within the block of {@code node} and returns the
     * store at the location of {@code node}. If {@code before} is true, then
     * the store immediately before the {@link Node} {@code node} is returned.
     * Otherwise, the store after {@code node} is returned.
     */
public static <A extends AbstractValue<A>, S extends Store<S>> S runAnalysisFor(Node node, boolean before, TransferInput<A, S> transferInput) {
    assert node != null;
    Block block = node.getBlock();
    assert transferInput != null;
    Analysis<A, S, ?> analysis = transferInput.analysis;
    Node oldCurrentNode = analysis.currentNode;
    if (analysis.isRunning) {
        return analysis.currentInput.getRegularStore();
    }
    analysis.isRunning = true;
    try {
        switch(block.getType()) {
            case REGULAR_BLOCK:
                {
                    RegularBlock rb = (RegularBlock) block;
                    // Apply transfer function to contents until we found the node
                    // we
                    // are looking for.
                    TransferInput<A, S> store = transferInput;
                    TransferResult<A, S> transferResult = null;
                    for (Node n : rb.getContents()) {
                        analysis.currentNode = n;
                        if (n == node && before) {
                            return store.getRegularStore();
                        }
                        transferResult = analysis.callTransferFunction(n, store);
                        if (n == node) {
                            return transferResult.getRegularStore();
                        }
                        store = new TransferInput<>(n, analysis, transferResult);
                    }
                    // 'block', then 'node' must be part of the contents of 'block'.
                    assert false;
                    return null;
                }
            case EXCEPTION_BLOCK:
                {
                    ExceptionBlock eb = (ExceptionBlock) block;
                    // apply transfer function to content
                    assert eb.getNode() == node;
                    if (before) {
                        return transferInput.getRegularStore();
                    }
                    analysis.currentNode = node;
                    TransferResult<A, S> transferResult = analysis.callTransferFunction(node, transferInput);
                    return transferResult.getRegularStore();
                }
            default:
                // Only regular blocks and exceptional blocks can hold nodes.
                assert false;
                break;
        }
        return null;
    } finally {
        analysis.currentNode = oldCurrentNode;
        analysis.isRunning = false;
    }
}
Also used : ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) Node(org.checkerframework.dataflow.cfg.node.Node) RegularBlock(org.checkerframework.dataflow.cfg.block.RegularBlock) Block(org.checkerframework.dataflow.cfg.block.Block) ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) RegularBlock(org.checkerframework.dataflow.cfg.block.RegularBlock)

Example 13 with ExceptionBlock

use of org.checkerframework.dataflow.cfg.block.ExceptionBlock in project checker-framework by typetools.

the class Analysis method performAnalysis.

/**
 * Perform the actual analysis. Should only be called once after the object has been created.
 */
public void performAnalysis(ControlFlowGraph cfg) {
    assert isRunning == false;
    isRunning = true;
    init(cfg);
    while (!worklist.isEmpty()) {
        Block b = worklist.poll();
        switch(b.getType()) {
            case REGULAR_BLOCK:
                {
                    RegularBlock rb = (RegularBlock) b;
                    // apply transfer function to contents
                    TransferInput<A, S> inputBefore = getInputBefore(rb);
                    currentInput = inputBefore.copy();
                    TransferResult<A, S> transferResult = null;
                    Node lastNode = null;
                    boolean addToWorklistAgain = false;
                    for (Node n : rb.getContents()) {
                        transferResult = callTransferFunction(n, currentInput);
                        addToWorklistAgain |= updateNodeValues(n, transferResult);
                        currentInput = new TransferInput<>(n, this, transferResult);
                        lastNode = n;
                    }
                    // loop will run at least once, making transferResult non-null
                    // propagate store to successors
                    Block succ = rb.getSuccessor();
                    assert succ != null : "regular basic block without non-exceptional successor unexpected";
                    propagateStoresTo(succ, lastNode, currentInput, rb.getFlowRule(), addToWorklistAgain);
                    break;
                }
            case EXCEPTION_BLOCK:
                {
                    ExceptionBlock eb = (ExceptionBlock) b;
                    // apply transfer function to content
                    TransferInput<A, S> inputBefore = getInputBefore(eb);
                    currentInput = inputBefore.copy();
                    Node node = eb.getNode();
                    TransferResult<A, S> transferResult = callTransferFunction(node, currentInput);
                    boolean addToWorklistAgain = updateNodeValues(node, transferResult);
                    // propagate store to successor
                    Block succ = eb.getSuccessor();
                    if (succ != null) {
                        currentInput = new TransferInput<>(node, this, transferResult);
                        // TODO? Variable wasn't used.
                        // Store.FlowRule storeFlow = eb.getFlowRule();
                        propagateStoresTo(succ, node, currentInput, eb.getFlowRule(), addToWorklistAgain);
                    }
                    // propagate store to exceptional successors
                    for (Entry<TypeMirror, Set<Block>> e : eb.getExceptionalSuccessors().entrySet()) {
                        TypeMirror cause = e.getKey();
                        S exceptionalStore = transferResult.getExceptionalStore(cause);
                        if (exceptionalStore != null) {
                            for (Block exceptionSucc : e.getValue()) {
                                addStoreBefore(exceptionSucc, node, exceptionalStore, Store.Kind.BOTH, addToWorklistAgain);
                            }
                        } else {
                            for (Block exceptionSucc : e.getValue()) {
                                addStoreBefore(exceptionSucc, node, inputBefore.copy().getRegularStore(), Store.Kind.BOTH, addToWorklistAgain);
                            }
                        }
                    }
                    break;
                }
            case CONDITIONAL_BLOCK:
                {
                    ConditionalBlock cb = (ConditionalBlock) b;
                    // get store before
                    TransferInput<A, S> inputBefore = getInputBefore(cb);
                    TransferInput<A, S> input = inputBefore.copy();
                    // propagate store to successor
                    Block thenSucc = cb.getThenSuccessor();
                    Block elseSucc = cb.getElseSuccessor();
                    propagateStoresTo(thenSucc, null, input, cb.getThenFlowRule(), false);
                    propagateStoresTo(elseSucc, null, input, cb.getElseFlowRule(), false);
                    break;
                }
            case SPECIAL_BLOCK:
                {
                    // special basic blocks are empty and cannot throw exceptions,
                    // thus there is no need to perform any analysis.
                    SpecialBlock sb = (SpecialBlock) b;
                    Block succ = sb.getSuccessor();
                    if (succ != null) {
                        propagateStoresTo(succ, null, getInputBefore(b), sb.getFlowRule(), false);
                    }
                    break;
                }
            default:
                assert false;
                break;
        }
    }
    assert isRunning == true;
    isRunning = false;
}
Also used : ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) Entry(java.util.Map.Entry) TypeMirror(javax.lang.model.type.TypeMirror) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) Node(org.checkerframework.dataflow.cfg.node.Node) ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) SpecialBlock(org.checkerframework.dataflow.cfg.block.SpecialBlock) Block(org.checkerframework.dataflow.cfg.block.Block) RegularBlock(org.checkerframework.dataflow.cfg.block.RegularBlock) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) SpecialBlock(org.checkerframework.dataflow.cfg.block.SpecialBlock) RegularBlock(org.checkerframework.dataflow.cfg.block.RegularBlock)

Example 14 with ExceptionBlock

use of org.checkerframework.dataflow.cfg.block.ExceptionBlock in project checker-framework by typetools.

the class DOTCFGVisualizer method generateDotGraph.

/**
 * Generate the dot representation as String.
 */
protected String generateDotGraph(ControlFlowGraph cfg, Block entry, @Nullable Analysis<A, S, T> analysis) {
    this.sbDigraph.setLength(0);
    Set<Block> visited = new HashSet<>();
    // header
    this.sbDigraph.append("digraph {\n");
    Block cur = entry;
    Queue<Block> worklist = new ArrayDeque<>();
    visited.add(entry);
    // traverse control flow graph and define all arrows
    while (true) {
        if (cur == null) {
            break;
        }
        if (cur.getType() == BlockType.CONDITIONAL_BLOCK) {
            ConditionalBlock ccur = ((ConditionalBlock) cur);
            Block thenSuccessor = ccur.getThenSuccessor();
            addDotEdge(ccur.getId(), thenSuccessor.getId(), "then\\n" + ccur.getThenFlowRule());
            if (!visited.contains(thenSuccessor)) {
                visited.add(thenSuccessor);
                worklist.add(thenSuccessor);
            }
            Block elseSuccessor = ccur.getElseSuccessor();
            addDotEdge(ccur.getId(), elseSuccessor.getId(), "else\\n" + ccur.getElseFlowRule());
            if (!visited.contains(elseSuccessor)) {
                visited.add(elseSuccessor);
                worklist.add(elseSuccessor);
            }
        } else {
            assert cur instanceof SingleSuccessorBlock;
            Block b = ((SingleSuccessorBlock) cur).getSuccessor();
            if (b != null) {
                addDotEdge(cur.getId(), b.getId(), ((SingleSuccessorBlock) cur).getFlowRule().name());
                if (!visited.contains(b)) {
                    visited.add(b);
                    worklist.add(b);
                }
            }
        }
        // exceptional edges
        if (cur.getType() == BlockType.EXCEPTION_BLOCK) {
            ExceptionBlock ecur = (ExceptionBlock) cur;
            for (Entry<TypeMirror, Set<Block>> e : ecur.getExceptionalSuccessors().entrySet()) {
                Set<Block> blocks = e.getValue();
                TypeMirror cause = e.getKey();
                String exception = cause.toString();
                if (exception.startsWith("java.lang.")) {
                    exception = exception.replace("java.lang.", "");
                }
                for (Block b : blocks) {
                    addDotEdge(cur.getId(), b.getId(), exception);
                    if (!visited.contains(b)) {
                        visited.add(b);
                        worklist.add(b);
                    }
                }
            }
        }
        cur = worklist.poll();
    }
    generateDotNodes(visited, cfg, analysis);
    // footer
    this.sbDigraph.append("}\n");
    return this.sbDigraph.toString();
}
Also used : ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) HashSet(java.util.HashSet) Set(java.util.Set) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) SingleSuccessorBlock(org.checkerframework.dataflow.cfg.block.SingleSuccessorBlock) TypeMirror(javax.lang.model.type.TypeMirror) ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) SpecialBlock(org.checkerframework.dataflow.cfg.block.SpecialBlock) Block(org.checkerframework.dataflow.cfg.block.Block) RegularBlock(org.checkerframework.dataflow.cfg.block.RegularBlock) SingleSuccessorBlock(org.checkerframework.dataflow.cfg.block.SingleSuccessorBlock) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) ArrayDeque(java.util.ArrayDeque) HashSet(java.util.HashSet)

Example 15 with ExceptionBlock

use of org.checkerframework.dataflow.cfg.block.ExceptionBlock in project checker-framework by typetools.

the class MustCallConsistencyAnalyzer method getSuccessorsExceptIgnoredExceptions.

/**
 * Get all successor blocks for some block, except for those corresponding to ignored exception
 * types. See {@link #ignoredExceptionTypes}. Each exceptional successor is paired with the type
 * of exception that leads to it, for use in error messages.
 *
 * @param block input block
 * @return set of pairs (b, t), where b is a successor block, and t is the type of exception for
 *     the CFG edge from block to b, or {@code null} if b is a non-exceptional successor
 */
private Set<Pair<Block, @Nullable TypeMirror>> getSuccessorsExceptIgnoredExceptions(Block block) {
    if (block.getType() == Block.BlockType.EXCEPTION_BLOCK) {
        ExceptionBlock excBlock = (ExceptionBlock) block;
        Set<Pair<Block, @Nullable TypeMirror>> result = new LinkedHashSet<>();
        // regular successor
        Block regularSucc = excBlock.getSuccessor();
        if (regularSucc != null) {
            result.add(Pair.of(regularSucc, null));
        }
        // non-ignored exception successors
        Map<TypeMirror, Set<Block>> exceptionalSuccessors = excBlock.getExceptionalSuccessors();
        for (Map.Entry<TypeMirror, Set<Block>> entry : exceptionalSuccessors.entrySet()) {
            TypeMirror exceptionType = entry.getKey();
            if (!isIgnoredExceptionType(((Type) exceptionType).tsym.getQualifiedName())) {
                for (Block exSucc : entry.getValue()) {
                    result.add(Pair.of(exSucc, exceptionType));
                }
            }
        }
        return result;
    } else {
        Set<Pair<Block, @Nullable TypeMirror>> result = new LinkedHashSet<>();
        for (Block b : block.getSuccessors()) {
            result.add(Pair.of(b, null));
        }
        return result;
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) Block(org.checkerframework.dataflow.cfg.block.Block) SingleSuccessorBlock(org.checkerframework.dataflow.cfg.block.SingleSuccessorBlock) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) Nullable(org.checkerframework.checker.nullness.qual.Nullable) Pair(org.checkerframework.javacutil.Pair)

Aggregations

ExceptionBlock (org.checkerframework.dataflow.cfg.block.ExceptionBlock)16 Block (org.checkerframework.dataflow.cfg.block.Block)14 TypeMirror (javax.lang.model.type.TypeMirror)10 ConditionalBlock (org.checkerframework.dataflow.cfg.block.ConditionalBlock)10 SpecialBlock (org.checkerframework.dataflow.cfg.block.SpecialBlock)10 RegularBlock (org.checkerframework.dataflow.cfg.block.RegularBlock)8 SingleSuccessorBlock (org.checkerframework.dataflow.cfg.block.SingleSuccessorBlock)8 Node (org.checkerframework.dataflow.cfg.node.Node)7 Set (java.util.Set)5 ReturnNode (org.checkerframework.dataflow.cfg.node.ReturnNode)5 HashSet (java.util.HashSet)4 AssignmentNode (org.checkerframework.dataflow.cfg.node.AssignmentNode)4 LocalVariableNode (org.checkerframework.dataflow.cfg.node.LocalVariableNode)4 LinkedHashSet (java.util.LinkedHashSet)3 LinkedList (java.util.LinkedList)3 List (java.util.List)3 Map (java.util.Map)3 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)3 ArrayDeque (java.util.ArrayDeque)2 IdentityHashMap (java.util.IdentityHashMap)2