Search in sources :

Example 16 with Block

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

the class ControlFlowGraph method getSuccessors.

/**
     * Get a list of all successor Blocks for cur
     * @param cur
     * @return A Deque of successor Blocks
     */
private Deque<Block> getSuccessors(Block cur) {
    Deque<Block> succs = new LinkedList<>();
    if (cur.getType() == BlockType.CONDITIONAL_BLOCK) {
        ConditionalBlock ccur = ((ConditionalBlock) cur);
        succs.add(ccur.getThenSuccessor());
        succs.add(ccur.getElseSuccessor());
    } else {
        assert cur instanceof SingleSuccessorBlock;
        Block b = ((SingleSuccessorBlock) cur).getSuccessor();
        if (b != null) {
            succs.add(b);
        }
    }
    if (cur.getType() == BlockType.EXCEPTION_BLOCK) {
        ExceptionBlock ecur = (ExceptionBlock) cur;
        for (Set<Block> exceptionSuccSet : ecur.getExceptionalSuccessors().values()) {
            succs.addAll(exceptionSuccSet);
        }
    }
    return succs;
}
Also used : ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) SingleSuccessorBlock(org.checkerframework.dataflow.cfg.block.SingleSuccessorBlock) ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) SingleSuccessorBlock(org.checkerframework.dataflow.cfg.block.SingleSuccessorBlock) SpecialBlock(org.checkerframework.dataflow.cfg.block.SpecialBlock) Block(org.checkerframework.dataflow.cfg.block.Block) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) LinkedList(java.util.LinkedList)

Example 17 with Block

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

the class ControlFlowGraph method getDepthFirstOrderedBlocks.

/**
     * @return The list of all basic block in this control flow graph
     * in reversed depth-first postorder sequence.
     *
     * Blocks may appear more than once in the sequence.
     */
public List<Block> getDepthFirstOrderedBlocks() {
    List<Block> dfsOrderResult = new LinkedList<>();
    Set<Block> visited = new HashSet<>();
    Deque<Block> worklist = new LinkedList<>();
    worklist.add(entryBlock);
    while (!worklist.isEmpty()) {
        Block cur = worklist.getLast();
        if (visited.contains(cur)) {
            dfsOrderResult.add(cur);
            worklist.removeLast();
        } else {
            visited.add(cur);
            Deque<Block> successors = getSuccessors(cur);
            successors.removeAll(visited);
            worklist.addAll(successors);
        }
    }
    Collections.reverse(dfsOrderResult);
    return dfsOrderResult;
}
Also used : ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) SingleSuccessorBlock(org.checkerframework.dataflow.cfg.block.SingleSuccessorBlock) SpecialBlock(org.checkerframework.dataflow.cfg.block.SpecialBlock) Block(org.checkerframework.dataflow.cfg.block.Block) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) LinkedList(java.util.LinkedList) HashSet(java.util.HashSet)

Example 18 with Block

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

the class ControlFlowGraph method getAllBlocks.

/**
     * @return The set of all basic block in this control flow graph.
     */
public Set<Block> getAllBlocks() {
    Set<Block> visited = new HashSet<>();
    Queue<Block> worklist = new LinkedList<>();
    Block cur = entryBlock;
    visited.add(entryBlock);
    // traverse the whole control flow graph
    while (true) {
        if (cur == null)
            break;
        Queue<Block> succs = new LinkedList<>();
        if (cur.getType() == BlockType.CONDITIONAL_BLOCK) {
            ConditionalBlock ccur = ((ConditionalBlock) cur);
            succs.add(ccur.getThenSuccessor());
            succs.add(ccur.getElseSuccessor());
        } else {
            assert cur instanceof SingleSuccessorBlock;
            Block b = ((SingleSuccessorBlock) cur).getSuccessor();
            if (b != null) {
                succs.add(b);
            }
        }
        if (cur.getType() == BlockType.EXCEPTION_BLOCK) {
            ExceptionBlock ecur = (ExceptionBlock) cur;
            for (Set<Block> exceptionSuccSet : ecur.getExceptionalSuccessors().values()) {
                succs.addAll(exceptionSuccSet);
            }
        }
        for (Block b : succs) {
            if (!visited.contains(b)) {
                visited.add(b);
                worklist.add(b);
            }
        }
        cur = worklist.poll();
    }
    return visited;
}
Also used : ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) SingleSuccessorBlock(org.checkerframework.dataflow.cfg.block.SingleSuccessorBlock) ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) SingleSuccessorBlock(org.checkerframework.dataflow.cfg.block.SingleSuccessorBlock) SpecialBlock(org.checkerframework.dataflow.cfg.block.SpecialBlock) Block(org.checkerframework.dataflow.cfg.block.Block) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) LinkedList(java.util.LinkedList) HashSet(java.util.HashSet)

Example 19 with Block

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

the class Analysis method init.

/** Initialize the analysis with a new control flow graph. */
protected void init(ControlFlowGraph cfg) {
    this.cfg = cfg;
    thenStores = new IdentityHashMap<>();
    elseStores = new IdentityHashMap<>();
    inputs = new IdentityHashMap<>();
    storesAtReturnStatements = new IdentityHashMap<>();
    worklist = new Worklist(cfg);
    nodeValues = new IdentityHashMap<>();
    finalLocalValues = new HashMap<>();
    worklist.add(cfg.getEntryBlock());
    List<LocalVariableNode> parameters = null;
    UnderlyingAST underlyingAST = cfg.getUnderlyingAST();
    if (underlyingAST.getKind() == Kind.METHOD) {
        MethodTree tree = ((CFGMethod) underlyingAST).getMethod();
        parameters = new ArrayList<>();
        for (VariableTree p : tree.getParameters()) {
            LocalVariableNode var = new LocalVariableNode(p);
            parameters.add(var);
        // TODO: document that LocalVariableNode has no block that it
        // belongs to
        }
    } else if (underlyingAST.getKind() == Kind.LAMBDA) {
        LambdaExpressionTree lambda = ((CFGLambda) underlyingAST).getLambdaTree();
        parameters = new ArrayList<>();
        for (VariableTree p : lambda.getParameters()) {
            LocalVariableNode var = new LocalVariableNode(p);
            parameters.add(var);
        // TODO: document that LocalVariableNode has no block that it
        // belongs to
        }
    } else {
    // nothing to do
    }
    S initialStore = transferFunction.initialStore(underlyingAST, parameters);
    Block entry = cfg.getEntryBlock();
    thenStores.put(entry, initialStore);
    elseStores.put(entry, initialStore);
    inputs.put(entry, new TransferInput<>(null, this, initialStore));
}
Also used : MethodTree(com.sun.source.tree.MethodTree) CFGMethod(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod) VariableTree(com.sun.source.tree.VariableTree) ArrayList(java.util.ArrayList) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) 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) UnderlyingAST(org.checkerframework.dataflow.cfg.UnderlyingAST)

Example 20 with Block

use of org.checkerframework.dataflow.cfg.block.Block 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)

Aggregations

Block (org.checkerframework.dataflow.cfg.block.Block)37 ExceptionBlock (org.checkerframework.dataflow.cfg.block.ExceptionBlock)30 ConditionalBlock (org.checkerframework.dataflow.cfg.block.ConditionalBlock)27 SpecialBlock (org.checkerframework.dataflow.cfg.block.SpecialBlock)25 RegularBlock (org.checkerframework.dataflow.cfg.block.RegularBlock)20 SingleSuccessorBlock (org.checkerframework.dataflow.cfg.block.SingleSuccessorBlock)18 HashSet (java.util.HashSet)10 ArrayList (java.util.ArrayList)9 List (java.util.List)9 TypeMirror (javax.lang.model.type.TypeMirror)9 Node (org.checkerframework.dataflow.cfg.node.Node)8 LocalVariableNode (org.checkerframework.dataflow.cfg.node.LocalVariableNode)7 ArrayDeque (java.util.ArrayDeque)6 IdentityHashMap (java.util.IdentityHashMap)6 LinkedHashSet (java.util.LinkedHashSet)6 Set (java.util.Set)6 BugInCF (org.checkerframework.javacutil.BugInCF)6 LinkedList (java.util.LinkedList)5 ReturnNode (org.checkerframework.dataflow.cfg.node.ReturnNode)5 Map (java.util.Map)4