Search in sources :

Example 26 with Block

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

Example 27 with Block

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

the class MustCallInferenceLogic method getNormalSuccessors.

/**
 * Returns the non-exceptional successors of the current block.
 *
 * @param cur the current block
 * @return the successors of this current block
 */
private List<Block> getNormalSuccessors(Block cur) {
    List<Block> successorBlock = new ArrayList<>();
    if (cur.getType() == Block.BlockType.CONDITIONAL_BLOCK) {
        ConditionalBlock ccur = (ConditionalBlock) cur;
        successorBlock.add(ccur.getThenSuccessor());
        successorBlock.add(ccur.getElseSuccessor());
    } else {
        if (!(cur instanceof SingleSuccessorBlock)) {
            throw new BugInCF("BlockImpl is neither a conditional block nor a SingleSuccessorBlock");
        }
        Block b = ((SingleSuccessorBlock) cur).getSuccessor();
        if (b != null) {
            successorBlock.add(b);
        }
    }
    return successorBlock;
}
Also used : ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) SingleSuccessorBlock(org.checkerframework.dataflow.cfg.block.SingleSuccessorBlock) ArrayList(java.util.ArrayList) SingleSuccessorBlock(org.checkerframework.dataflow.cfg.block.SingleSuccessorBlock) Block(org.checkerframework.dataflow.cfg.block.Block) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) BugInCF(org.checkerframework.javacutil.BugInCF)

Example 28 with Block

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

the class MustCallInferenceLogic method runInference.

/**
 * Runs the inference algorithm on the contents of the {@link #cfg} field.
 *
 * <p>Operationally, it checks method invocations for fields with non-empty @MustCall obligations
 * along all paths to the regular exit point in the method body of the method represented by
 * {@link #cfg}, and updates the {@link #owningFields} set if it discovers an owning field whose
 * must-call obligations were satisfied along one of the checked paths.
 */
void runInference() {
    Set<Block> visited = new HashSet<>();
    Deque<Block> worklist = new ArrayDeque<>();
    Block entry = this.cfg.getEntryBlock();
    worklist.add(entry);
    visited.add(entry);
    while (!worklist.isEmpty()) {
        Block current = worklist.remove();
        for (Node node : current.getNodes()) {
            if (node instanceof MethodInvocationNode) {
                checkForMustCallInvocationOnField((MethodInvocationNode) node);
            }
        }
        propagateRegPaths(current, visited, worklist);
    }
}
Also used : MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) Node(org.checkerframework.dataflow.cfg.node.Node) SingleSuccessorBlock(org.checkerframework.dataflow.cfg.block.SingleSuccessorBlock) Block(org.checkerframework.dataflow.cfg.block.Block) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) ArrayDeque(java.util.ArrayDeque) HashSet(java.util.HashSet)

Example 29 with Block

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

the class StringCFGVisualizer method visualizeNodes.

@SuppressWarnings("keyfor:enhancedfor")
@Override
public String visualizeNodes(Set<Block> blocks, ControlFlowGraph cfg, @Nullable Analysis<V, S, T> analysis) {
    StringJoiner sjStringNodes = new StringJoiner(lineSeparator);
    IdentityHashMap<Block, List<Integer>> processOrder = getProcessOrder(cfg);
    // Generate all the Nodes.
    for (@KeyFor("processOrder") Block v : blocks) {
        sjStringNodes.add(v.getUid() + ":");
        if (verbose) {
            sjStringNodes.add(getProcessOrderSimpleString(processOrder.get(v)));
        }
        sjStringNodes.add(visualizeBlock(v, analysis));
        sjStringNodes.add("");
    }
    return sjStringNodes.toString().trim();
}
Also used : KeyFor(org.checkerframework.checker.nullness.qual.KeyFor) SpecialBlock(org.checkerframework.dataflow.cfg.block.SpecialBlock) Block(org.checkerframework.dataflow.cfg.block.Block) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) List(java.util.List) StringJoiner(java.util.StringJoiner)

Example 30 with Block

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

the class AbstractCFGVisualizer method getProcessOrder.

/**
 * Generate the order of processing blocks. Because a block may appears more than once in {@link
 * ControlFlowGraph#getDepthFirstOrderedBlocks()}, the orders of each block are stored in a
 * separate array list.
 *
 * @param cfg the current control flow graph
 * @return an IdentityHashMap that maps from blocks to their orders
 */
protected IdentityHashMap<Block, List<Integer>> getProcessOrder(ControlFlowGraph cfg) {
    IdentityHashMap<Block, List<Integer>> depthFirstOrder = new IdentityHashMap<>();
    int count = 1;
    for (Block b : cfg.getDepthFirstOrderedBlocks()) {
        depthFirstOrder.computeIfAbsent(b, k -> new ArrayList<>());
        // computeIfAbsent's function doesn't return null
        @SuppressWarnings("nullness:assignment") @NonNull List<Integer> blockIds = depthFirstOrder.get(b);
        blockIds.add(count++);
    }
    return depthFirstOrder;
}
Also used : IdentityHashMap(java.util.IdentityHashMap) NonNull(org.checkerframework.checker.nullness.qual.NonNull) ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) SpecialBlock(org.checkerframework.dataflow.cfg.block.SpecialBlock) Block(org.checkerframework.dataflow.cfg.block.Block) SingleSuccessorBlock(org.checkerframework.dataflow.cfg.block.SingleSuccessorBlock) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) ArrayList(java.util.ArrayList) List(java.util.List)

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