Search in sources :

Example 16 with ExceptionBlock

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

the class ForwardAnalysisImpl method runAnalysisFor.

@Override
public S runAnalysisFor(@FindDistinct Node node, Analysis.BeforeOrAfter preOrPost, TransferInput<V, S> blockTransferInput, IdentityHashMap<Node, V> nodeValues, Map<TransferInput<V, S>, IdentityHashMap<Node, TransferResult<V, S>>> analysisCaches) {
    Block block = node.getBlock();
    assert block != null : "@AssumeAssertion(nullness): invariant";
    Node oldCurrentNode = currentNode;
    // Prepare cache
    IdentityHashMap<Node, TransferResult<V, S>> cache;
    if (analysisCaches != null) {
        cache = analysisCaches.computeIfAbsent(blockTransferInput, __ -> new IdentityHashMap<>());
    } else {
        cache = null;
    }
    if (isRunning) {
        assert currentInput != null : "@AssumeAssertion(nullness): invariant";
        return currentInput.getRegularStore();
    }
    setNodeValues(nodeValues);
    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<V, S> store = blockTransferInput;
                    TransferResult<V, S> transferResult;
                    for (Node n : rb.getNodes()) {
                        setCurrentNode(n);
                        if (n == node && preOrPost == Analysis.BeforeOrAfter.BEFORE) {
                            return store.getRegularStore();
                        }
                        if (cache != null && cache.containsKey(n)) {
                            transferResult = cache.get(n);
                        } else {
                            // Copy the store to avoid changing other blocks' transfer inputs in {@link #inputs}
                            transferResult = callTransferFunction(n, store.copy());
                            if (cache != null) {
                                cache.put(n, transferResult);
                            }
                        }
                        if (n == node) {
                            return transferResult.getRegularStore();
                        }
                        store = new TransferInput<>(n, this, transferResult);
                    }
                    throw new BugInCF("node %s is not in node.getBlock()=%s", node, block);
                }
            case EXCEPTION_BLOCK:
                {
                    ExceptionBlock eb = (ExceptionBlock) block;
                    // Apply the transfer function to content
                    if (eb.getNode() != node) {
                        throw new BugInCF("Node should be equal to eb.getNode(). But get: node: " + node + "\teb.getNode(): " + eb.getNode());
                    }
                    if (preOrPost == Analysis.BeforeOrAfter.BEFORE) {
                        return blockTransferInput.getRegularStore();
                    }
                    setCurrentNode(node);
                    // Copy the store to avoid changing other blocks' transfer inputs in {@link #inputs}
                    TransferResult<V, S> transferResult;
                    if (cache != null && cache.containsKey(node)) {
                        transferResult = cache.get(node);
                    } else {
                        // Copy the store to avoid changing other blocks' transfer inputs in {@link #inputs}
                        transferResult = callTransferFunction(node, blockTransferInput.copy());
                        if (cache != null) {
                            cache.put(node, transferResult);
                        }
                    }
                    return transferResult.getRegularStore();
                }
            default:
                // Only regular blocks and exceptional blocks can hold nodes.
                throw new BugInCF("Unexpected block type: " + block.getType());
        }
    } finally {
        setCurrentNode(oldCurrentNode);
        isRunning = false;
    }
}
Also used : BugInCF(org.checkerframework.javacutil.BugInCF) MethodTree(com.sun.source.tree.MethodTree) ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) FindDistinct(org.checkerframework.checker.interning.qual.FindDistinct) Map(java.util.Map) SpecialBlock(org.checkerframework.dataflow.cfg.block.SpecialBlock) Block(org.checkerframework.dataflow.cfg.block.Block) Pair(org.checkerframework.javacutil.Pair) Nullable(org.checkerframework.checker.nullness.qual.Nullable) SideEffectFree(org.checkerframework.dataflow.qual.SideEffectFree) IdentityHashMap(java.util.IdentityHashMap) UnderlyingAST(org.checkerframework.dataflow.cfg.UnderlyingAST) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) Set(java.util.Set) ControlFlowGraph(org.checkerframework.dataflow.cfg.ControlFlowGraph) RegularBlock(org.checkerframework.dataflow.cfg.block.RegularBlock) RequiresNonNull(org.checkerframework.checker.nullness.qual.RequiresNonNull) CFGMethod(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) List(java.util.List) TypeMirror(javax.lang.model.type.TypeMirror) CFGLambda(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGLambda) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) Collections(java.util.Collections) Node(org.checkerframework.dataflow.cfg.node.Node) CollectionsPlume(org.plumelib.util.CollectionsPlume) ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) Node(org.checkerframework.dataflow.cfg.node.Node) IdentityHashMap(java.util.IdentityHashMap) 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) RegularBlock(org.checkerframework.dataflow.cfg.block.RegularBlock) BugInCF(org.checkerframework.javacutil.BugInCF)

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