Search in sources :

Example 31 with Block

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

the class ForwardAnalysisImpl method initInitialInputs.

@Override
@RequiresNonNull("cfg")
protected void initInitialInputs() {
    worklist.process(cfg);
    Block entry = cfg.getEntryBlock();
    worklist.add(entry);
    UnderlyingAST underlyingAST = cfg.getUnderlyingAST();
    List<LocalVariableNode> parameters = getParameters(underlyingAST);
    assert transferFunction != null : "@AssumeAssertion(nullness): invariant";
    S initialStore = transferFunction.initialStore(underlyingAST, parameters);
    thenStores.put(entry, initialStore);
    elseStores.put(entry, initialStore);
    inputs.put(entry, new TransferInput<>(null, this, initialStore));
}
Also used : 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) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) UnderlyingAST(org.checkerframework.dataflow.cfg.UnderlyingAST) RequiresNonNull(org.checkerframework.checker.nullness.qual.RequiresNonNull)

Example 32 with Block

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

Example 33 with Block

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

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.
 *
 * <p>If the given {@link Node} cannot be reached (in the control flow graph), then {@code null}
 * is returned.
 *
 * @param node the node to analyze
 * @param preOrPost which store to return: the store immediately before {@code node} or the store
 *     after {@code node}
 * @return the store before or after {@code node} (depends on the value of {@code before}) after
 *     running the analysis
 */
@Nullable
protected S runAnalysisFor(Node node, Analysis.BeforeOrAfter preOrPost) {
    Block block = node.getBlock();
    assert block != null : "@AssumeAssertion(nullness): invariant";
    TransferInput<V, S> transferInput = stores.get(block);
    if (transferInput == null) {
        return null;
    }
    return runAnalysisFor(node, preOrPost, transferInput, nodeValues, analysisCaches);
}
Also used : ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) Block(org.checkerframework.dataflow.cfg.block.Block) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Example 34 with Block

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

the class BackwardAnalysisImpl method performAnalysis.

@Override
public void performAnalysis(ControlFlowGraph cfg) {
    if (isRunning) {
        throw new BugInCF("performAnalysis() shouldn't be called when the analysis is running.");
    }
    isRunning = true;
    try {
        init(cfg);
        while (!worklist.isEmpty()) {
            Block b = worklist.poll();
            performAnalysisBlock(b);
        }
    } finally {
        assert isRunning;
        // In case performAnalysisBlock crashed, reset isRunning to false.
        isRunning = false;
    }
}
Also used : RegularBlock(org.checkerframework.dataflow.cfg.block.RegularBlock) ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) SpecialBlock(org.checkerframework.dataflow.cfg.block.SpecialBlock) Block(org.checkerframework.dataflow.cfg.block.Block) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) BugInCF(org.checkerframework.javacutil.BugInCF)

Example 35 with Block

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

the class CFGTranslationPhaseThree method getPredecessorHolder.

/**
 * Return a predecessor holder that can be used to set the successor of {@code pred} in the place
 * where previously the edge pointed to {@code cur}. Additionally, the predecessor holder also
 * takes care of unlinking (i.e., removing the {@code pred} from {@code cur's} predecessors).
 *
 * @param pred a block whose successor should be set
 * @param cur the previous successor of {@code pred}
 * @return a predecessor holder to set the successor of {@code pred}
 */
// AST node comparisons
@SuppressWarnings("interning:not.interned")
protected static PredecessorHolder getPredecessorHolder(final BlockImpl pred, final BlockImpl cur) {
    switch(pred.getType()) {
        case SPECIAL_BLOCK:
            SingleSuccessorBlockImpl s = (SingleSuccessorBlockImpl) pred;
            return singleSuccessorHolder(s, cur);
        case CONDITIONAL_BLOCK:
            // add pred correctly to predecessor list
            final ConditionalBlockImpl c = (ConditionalBlockImpl) pred;
            if (c.getThenSuccessor() == cur) {
                return new PredecessorHolder() {

                    @Override
                    public void setSuccessor(BlockImpl b) {
                        c.setThenSuccessor(b);
                        cur.removePredecessor(pred);
                    }

                    @Override
                    public BlockImpl getBlock() {
                        return c;
                    }
                };
            } else {
                assert c.getElseSuccessor() == cur;
                return new PredecessorHolder() {

                    @Override
                    public void setSuccessor(BlockImpl b) {
                        c.setElseSuccessor(b);
                        cur.removePredecessor(pred);
                    }

                    @Override
                    public BlockImpl getBlock() {
                        return c;
                    }
                };
            }
        case EXCEPTION_BLOCK:
            // add pred correctly to predecessor list
            final ExceptionBlockImpl e = (ExceptionBlockImpl) pred;
            if (e.getSuccessor() == cur) {
                return singleSuccessorHolder(e, cur);
            } else {
                // ignore keyfor type
                @SuppressWarnings("keyfor:assignment") Set<Map.Entry<TypeMirror, Set<Block>>> entrySet = e.getExceptionalSuccessors().entrySet();
                for (final Map.Entry<TypeMirror, Set<Block>> entry : entrySet) {
                    if (entry.getValue().contains(cur)) {
                        return new PredecessorHolder() {

                            @Override
                            public void setSuccessor(BlockImpl b) {
                                e.addExceptionalSuccessor(b, entry.getKey());
                                cur.removePredecessor(pred);
                            }

                            @Override
                            public BlockImpl getBlock() {
                                return e;
                            }
                        };
                    }
                }
            }
            throw new BugInCF("Unreachable");
        case REGULAR_BLOCK:
            RegularBlockImpl r = (RegularBlockImpl) pred;
            return singleSuccessorHolder(r, cur);
        default:
            throw new BugInCF("Unexpected block type " + pred.getType());
    }
}
Also used : ExceptionBlockImpl(org.checkerframework.dataflow.cfg.block.ExceptionBlockImpl) BlockImpl(org.checkerframework.dataflow.cfg.block.BlockImpl) RegularBlockImpl(org.checkerframework.dataflow.cfg.block.RegularBlockImpl) ConditionalBlockImpl(org.checkerframework.dataflow.cfg.block.ConditionalBlockImpl) SingleSuccessorBlockImpl(org.checkerframework.dataflow.cfg.block.SingleSuccessorBlockImpl) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) ExceptionBlockImpl(org.checkerframework.dataflow.cfg.block.ExceptionBlockImpl) BugInCF(org.checkerframework.javacutil.BugInCF) SingleSuccessorBlockImpl(org.checkerframework.dataflow.cfg.block.SingleSuccessorBlockImpl) RegularBlockImpl(org.checkerframework.dataflow.cfg.block.RegularBlockImpl) ConditionalBlockImpl(org.checkerframework.dataflow.cfg.block.ConditionalBlockImpl) TypeMirror(javax.lang.model.type.TypeMirror) Block(org.checkerframework.dataflow.cfg.block.Block) Map(java.util.Map)

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