Search in sources :

Example 1 with FindDistinct

use of org.checkerframework.checker.interning.qual.FindDistinct 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

LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)1 MethodTree (com.sun.source.tree.MethodTree)1 Collections (java.util.Collections)1 IdentityHashMap (java.util.IdentityHashMap)1 List (java.util.List)1 Map (java.util.Map)1 Set (java.util.Set)1 TypeMirror (javax.lang.model.type.TypeMirror)1 FindDistinct (org.checkerframework.checker.interning.qual.FindDistinct)1 Nullable (org.checkerframework.checker.nullness.qual.Nullable)1 RequiresNonNull (org.checkerframework.checker.nullness.qual.RequiresNonNull)1 ControlFlowGraph (org.checkerframework.dataflow.cfg.ControlFlowGraph)1 UnderlyingAST (org.checkerframework.dataflow.cfg.UnderlyingAST)1 CFGLambda (org.checkerframework.dataflow.cfg.UnderlyingAST.CFGLambda)1 CFGMethod (org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod)1 Block (org.checkerframework.dataflow.cfg.block.Block)1 ConditionalBlock (org.checkerframework.dataflow.cfg.block.ConditionalBlock)1 ExceptionBlock (org.checkerframework.dataflow.cfg.block.ExceptionBlock)1 RegularBlock (org.checkerframework.dataflow.cfg.block.RegularBlock)1 SpecialBlock (org.checkerframework.dataflow.cfg.block.SpecialBlock)1