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;
}
}
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;
}
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);
}
}
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();
}
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;
}
Aggregations