Search in sources :

Example 1 with MustCallAnnotatedTypeFactory

use of org.checkerframework.checker.mustcall.MustCallAnnotatedTypeFactory in project checker-framework by typetools.

the class MustCallConsistencyAnalyzer method propagateObligationsToSuccessorBlocks.

/**
 * Propagates a set of Obligations to successors, and performs consistency checks when variables
 * are going out of scope.
 *
 * <p>The basic algorithm loops over the successor blocks of the current block. For each
 * successor, it checks every Obligation in obligations. If the successor is an exit block or all
 * of an Obligation's resource aliases might be going out of scope, then a consistency check
 * occurs (with two exceptions, both related to temporary variables that don't actually get
 * assigned; see code comments for details) and an error is issued if it fails. If the successor
 * is any other kind of block and there is information about at least one of the Obligation's
 * aliases in the successor store (i.e. the resource itself definitely does not go out of scope),
 * then the Obligation is passed forward to the successor ("propagated") with any definitely
 * out-of-scope aliases removed from its resource alias set.
 *
 * @param obligations Obligations for the current block
 * @param currentBlock the current block
 * @param visited block-Obligations pairs already analyzed or already on the worklist
 * @param worklist current worklist
 */
private void propagateObligationsToSuccessorBlocks(Set<Obligation> obligations, Block currentBlock, Set<BlockWithObligations> visited, Deque<BlockWithObligations> worklist) {
    List<Node> currentBlockNodes = currentBlock.getNodes();
    // loop performs a consistency check for that Obligation.
    for (Pair<Block, @Nullable TypeMirror> successorAndExceptionType : getSuccessorsExceptIgnoredExceptions(currentBlock)) {
        Block successor = successorAndExceptionType.first;
        // If nonnull, currentBlock is an ExceptionBlock.
        TypeMirror exceptionType = successorAndExceptionType.second;
        // successorObligations eventually contains the Obligations to propagate to successor. The
        // loop below mutates it.
        Set<Obligation> successorObligations = new LinkedHashSet<>();
        // A detailed reason to give in the case that the last resource alias of an Obligation
        // goes out of scope without a called-methods type that satisfies the corresponding
        // must-call obligation along the current control-flow edge. Computed here for efficiency;
        // used in the loop over the Obligations, below.
        String exitReasonForErrorMessage = exceptionType == null ? // doesn't seem to provide additional helpful information.
        "regular method exit" : "possible exceptional exit due to " + ((ExceptionBlock) currentBlock).getNode().getTree() + " with exception type " + exceptionType;
        // Computed outside the Obligation loop for efficiency.
        CFStore regularStoreOfSuccessor = analysis.getInput(successor).getRegularStore();
        for (Obligation obligation : obligations) {
            // This boolean is true if there is no evidence that the Obligation does not go out of
            // scope - that is, if there is definitely a resource alias that is in scope in the
            // successor.
            boolean obligationGoesOutOfScopeBeforeSuccessor = true;
            for (ResourceAlias resourceAlias : obligation.resourceAliases) {
                if (aliasInScopeInSuccessor(regularStoreOfSuccessor, resourceAlias)) {
                    obligationGoesOutOfScopeBeforeSuccessor = false;
                    break;
                }
            }
            // should occur.
            if (successor.getType() == BlockType.SPECIAL_BLOCK || /* special blocks are exit blocks */
            obligationGoesOutOfScopeBeforeSuccessor) {
                MustCallAnnotatedTypeFactory mcAtf = typeFactory.getTypeFactoryOfSubchecker(MustCallChecker.class);
                // are ignored. Whether exceptionType is null captures the logic of both of these cases.
                if (exceptionType != null) {
                    Node exceptionalNode = NodeUtils.removeCasts(((ExceptionBlock) currentBlock).getNode());
                    LocalVariableNode tmpVarForExcNode = typeFactory.getTempVarForNode(exceptionalNode);
                    if (tmpVarForExcNode != null && obligation.resourceAliases.size() == 1 && obligation.canBeSatisfiedThrough(tmpVarForExcNode)) {
                        continue;
                    }
                }
                // unwrapped at various points in the analysis.
                if (currentBlockNodes.size() == 1 && inCast(currentBlockNodes.get(0))) {
                    successorObligations.add(obligation);
                    continue;
                }
                // being resolved some other way.
                if (obligation.derivedFromMustCallAlias()) {
                    checker.reportError(obligation.resourceAliases.asList().get(0).tree, "mustcallalias.out.of.scope", exitReasonForErrorMessage);
                    continue;
                }
                // Which stores from the called-methods and must-call checkers are used in
                // the consistency check varies depending on the context. The rules are:
                // 1. if the current block has no nodes (and therefore the store must come from a block
                // rather than a node):
                // 1a. if there is information about any alias in the resource alias set
                // in the successor store, use the successor's CM and MC stores, which
                // contain whatever information is true after this block finishes.
                // 1b. if there is not any information about any alias in the resource alias
                // set in the successor store, use the current blocks' CM and MC stores,
                // which contain whatever information is true before this (empty) block.
                // 2. if the current block has one or more nodes, always use the CM store after
                // the last node. To decide which MC store to use:
                // 2a. if the last node in the block is the invocation of an @CreatesMustCallFor
                // method that might throw an exception, and the consistency check is for
                // an exceptional path, use the MC store immediately before the method invocation,
                // because the method threw an exception rather than finishing and therefore did
                // not actually create any must-call obligation, so the MC store after might
                // contain must-call obligations that do not need to be fulfilled along this path.
                // 2b. in all other cases, use the MC store from after the last node in the block.
                CFStore mcStore, cmStore;
                if (currentBlockNodes.size() == 0) /* currentBlock is special or conditional */
                {
                    cmStore = obligationGoesOutOfScopeBeforeSuccessor ? // 1a. (CM)
                    analysis.getInput(currentBlock).getRegularStore() : // 1b. (CM)
                    regularStoreOfSuccessor;
                    mcStore = mcAtf.getStoreForBlock(obligationGoesOutOfScopeBeforeSuccessor, // 1a. (MC)
                    currentBlock, // 1b. (MC)
                    successor);
                } else {
                    // In this case, current block has at least one node.
                    // Use the called-methods store immediately after the last node in currentBlock.
                    // 2. (CM)
                    Node last = currentBlockNodes.get(currentBlockNodes.size() - 1);
                    cmStore = typeFactory.getStoreAfter(last);
                    // an exception. Otherwise, use the store after.
                    if (exceptionType != null && isInvocationOfCreatesMustCallForMethod(last)) {
                        // 2a. (MC)
                        mcStore = mcAtf.getStoreBefore(last);
                    } else {
                        // 2b. (MC)
                        mcStore = mcAtf.getStoreAfter(last);
                    }
                }
                checkMustCall(obligation, cmStore, mcStore, exitReasonForErrorMessage);
            } else {
                // In this case, there is info in the successor store about some alias in the Obligation.
                // Handles the possibility that some resource in the Obligation may go out of scope.
                Set<ResourceAlias> copyOfResourceAliases = new LinkedHashSet<>(obligation.resourceAliases);
                copyOfResourceAliases.removeIf(alias -> !aliasInScopeInSuccessor(regularStoreOfSuccessor, alias));
                successorObligations.add(new Obligation(copyOfResourceAliases));
            }
        }
        propagate(new BlockWithObligations(successor, successorObligations), visited, worklist);
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) CFStore(org.checkerframework.framework.flow.CFStore) TypeCastNode(org.checkerframework.dataflow.cfg.node.TypeCastNode) ObjectCreationNode(org.checkerframework.dataflow.cfg.node.ObjectCreationNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) ThisNode(org.checkerframework.dataflow.cfg.node.ThisNode) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) NullLiteralNode(org.checkerframework.dataflow.cfg.node.NullLiteralNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) Node(org.checkerframework.dataflow.cfg.node.Node) MustCallAnnotatedTypeFactory(org.checkerframework.checker.mustcall.MustCallAnnotatedTypeFactory) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) 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)

Example 2 with MustCallAnnotatedTypeFactory

use of org.checkerframework.checker.mustcall.MustCallAnnotatedTypeFactory in project checker-framework by typetools.

the class MustCallConsistencyAnalyzer method updateObligationsForPseudoAssignment.

/**
 * Update a set of tracked Obligations to account for a (pseudo-)assignment to some variable, as
 * in a gen-kill dataflow analysis problem. That is, add ("gen") and remove ("kill") resource
 * aliases from Obligations in the {@code obligations} set as appropriate based on the
 * (pseudo-)assignment performed by {@code node}. This method may also remove an Obligation
 * entirely if the analysis concludes that its resource alias set is empty because the last
 * tracked alias to it has been overwritten (including checking that the must-call obligations
 * were satisfied before the assignment).
 *
 * <p>Pseudo-assignments may include operations that "assign" to a temporary variable, exposing
 * the possible value flow into the variable. E.g., for a ternary expression {@code b ? x : y}
 * whose temporary variable is {@code t}, this method may process "assignments" {@code t = x} and
 * {@code t = y}, thereby capturing the two possible values of {@code t}.
 *
 * @param obligations the tracked Obligations, which will be side-effected
 * @param node the node performing the pseudo-assignment; it is not necessarily an assignment node
 * @param lhsVar the left-hand side variable for the pseudo-assignment
 * @param rhs the right-hand side for the pseudo-assignment, which must have been converted to a
 *     temporary variable (via a call to {@link
 *     ResourceLeakAnnotatedTypeFactory#getTempVarForNode})
 */
private void updateObligationsForPseudoAssignment(Set<Obligation> obligations, Node node, LocalVariableNode lhsVar, Node rhs) {
    // Replacements to eventually perform in Obligations.  This map is kept to avoid a
    // ConcurrentModificationException in the loop below.
    Map<Obligation, Obligation> replacements = new LinkedHashMap<>();
    // Cache to re-use on subsequent iterations.
    ResourceAlias aliasForAssignment = null;
    for (Obligation obligation : obligations) {
        // This is a non-null value iff the resource alias set for obligation needs to
        // change because of the pseudo-assignment. The value of this variable is the new
        // alias set for `obligation` if it is non-null.
        Set<ResourceAlias> newResourceAliasesForObligation = null;
        // Always kill the lhs var if it is present in the resource alias set for this Obligation
        // by removing it from the resource alias set.
        ResourceAlias aliasForLhs = obligation.getResourceAlias(lhsVar);
        if (aliasForLhs != null) {
            newResourceAliasesForObligation = new LinkedHashSet<>(obligation.resourceAliases);
            newResourceAliasesForObligation.remove(aliasForLhs);
        }
        // by adding it to the resource alias set.
        if (rhs instanceof LocalVariableNode && obligation.canBeSatisfiedThrough((LocalVariableNode) rhs)) {
            LocalVariableNode rhsVar = (LocalVariableNode) rhs;
            if (newResourceAliasesForObligation == null) {
                newResourceAliasesForObligation = new LinkedHashSet<>(obligation.resourceAliases);
            }
            if (aliasForAssignment == null) {
                // It is possible to observe assignments to temporary variables, e.g.,
                // synthetic assignments to ternary expression variables in the CFG.  For such
                // cases, use the tree associated with the temp var for the resource alias,
                // as that is the tree where errors should be reported.
                Tree treeForAlias = typeFactory.isTempVar(lhsVar) ? typeFactory.getTreeForTempVar(lhsVar) : node.getTree();
                aliasForAssignment = new ResourceAlias(new LocalVariable(lhsVar), treeForAlias);
            }
            newResourceAliasesForObligation.add(aliasForAssignment);
            // Remove temp vars from tracking once they are assigned to another location.
            if (typeFactory.isTempVar(rhsVar)) {
                ResourceAlias aliasForRhs = obligation.getResourceAlias(rhsVar);
                if (aliasForRhs != null) {
                    newResourceAliasesForObligation.remove(aliasForRhs);
                }
            }
        }
        // Obligation.
        if (newResourceAliasesForObligation == null) {
            continue;
        }
        if (newResourceAliasesForObligation.isEmpty()) {
            // Because the last reference to the resource has been overwritten, check the must-call
            // obligation.
            MustCallAnnotatedTypeFactory mcAtf = typeFactory.getTypeFactoryOfSubchecker(MustCallChecker.class);
            checkMustCall(obligation, typeFactory.getStoreBefore(node), mcAtf.getStoreBefore(node), "variable overwritten by assignment " + node.getTree());
            replacements.put(obligation, null);
        } else {
            replacements.put(obligation, new Obligation(newResourceAliasesForObligation));
        }
    }
    // Finally, update the set of Obligations according to the replacements.
    for (Map.Entry<Obligation, Obligation> entry : replacements.entrySet()) {
        obligations.remove(entry.getKey());
        if (entry.getValue() != null && !entry.getValue().resourceAliases.isEmpty()) {
            obligations.add(entry.getValue());
        }
    }
}
Also used : LocalVariable(org.checkerframework.dataflow.expression.LocalVariable) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) MustCallAnnotatedTypeFactory(org.checkerframework.checker.mustcall.MustCallAnnotatedTypeFactory) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) LinkedHashMap(java.util.LinkedHashMap)

Example 3 with MustCallAnnotatedTypeFactory

use of org.checkerframework.checker.mustcall.MustCallAnnotatedTypeFactory in project checker-framework by typetools.

the class MustCallConsistencyAnalyzer method checkReassignmentToField.

/**
 * Issues an error if the given re-assignment to a non-final, owning field is not valid. A
 * re-assignment is valid if the called methods type of the lhs before the assignment satisfies
 * the must-call obligations of the field.
 *
 * @param obligations current tracked Obligations
 * @param node an assignment to a non-final, owning field
 */
private void checkReassignmentToField(Set<Obligation> obligations, AssignmentNode node) {
    Node lhsNode = node.getTarget();
    if (!(lhsNode instanceof FieldAccessNode)) {
        throw new TypeSystemError("checkReassignmentToField: non-field node " + node + " of class " + node.getClass());
    }
    FieldAccessNode lhs = (FieldAccessNode) lhsNode;
    Node receiver = lhs.getReceiver();
    // TODO: it would be better to defer getting the path until after checking
    // for a CreatesMustCallFor annotation, because getting the path can be expensive.
    // It might be possible to exploit the CFG structure to find the containing
    // method (rather than using the path, as below), because if a method is being
    // analyzed then it should be the root of the CFG (I think).
    TreePath currentPath = typeFactory.getPath(node.getTree());
    MethodTree enclosingMethodTree = TreePathUtil.enclosingMethod(currentPath);
    if (enclosingMethodTree == null) {
        // also a declaration must be a field initializer.
        if (node.getTree().getKind() == Tree.Kind.VARIABLE) {
            return;
        } else {
            // Issue an error if the field has a non-empty must-call type.
            MustCallAnnotatedTypeFactory mcTypeFactory = typeFactory.getTypeFactoryOfSubchecker(MustCallChecker.class);
            AnnotationMirror mcAnno = mcTypeFactory.getAnnotatedType(lhs.getElement()).getAnnotation(MustCall.class);
            List<String> mcValues = AnnotationUtils.getElementValueArray(mcAnno, mcTypeFactory.getMustCallValueElement(), String.class);
            if (mcValues.isEmpty()) {
                return;
            }
            Element lhsElement = TreeUtils.elementFromTree(lhs.getTree());
            checker.reportError(node.getTree(), "required.method.not.called", formatMissingMustCallMethods(mcValues), "field " + lhsElement.getSimpleName().toString(), lhsElement.asType().toString(), "Field assignment outside method or declaration might overwrite field's current value");
            return;
        }
    }
    // on the method declaration), or 2) the rhs is a null literal (so there's nothing to reset).
    if (!(receiver instanceof LocalVariableNode && varTrackedInObligations(obligations, (LocalVariableNode) receiver)) && !(node.getExpression() instanceof NullLiteralNode)) {
        checkEnclosingMethodIsCreatesMustCallFor(node, enclosingMethodTree);
    }
    MustCallAnnotatedTypeFactory mcTypeFactory = typeFactory.getTypeFactoryOfSubchecker(MustCallChecker.class);
    // Get the Must Call type for the field. If there's info about this field in the store, use
    // that. Otherwise, use the declared type of the field
    CFStore mcStore = mcTypeFactory.getStoreBefore(lhs);
    CFValue mcValue = mcStore.getValue(lhs);
    AnnotationMirror mcAnno;
    if (mcValue == null) {
        // No store value, so use the declared type.
        mcAnno = mcTypeFactory.getAnnotatedType(lhs.getElement()).getAnnotation(MustCall.class);
    } else {
        mcAnno = AnnotationUtils.getAnnotationByClass(mcValue.getAnnotations(), MustCall.class);
    }
    List<String> mcValues = AnnotationUtils.getElementValueArray(mcAnno, mcTypeFactory.getMustCallValueElement(), String.class);
    if (mcValues.isEmpty()) {
        return;
    }
    // Get the store before the RHS rather than the assignment node, because the CFG always has
    // the RHS first. If the RHS has side-effects, then the assignment node's store will have
    // had its inferred types erased.
    Node rhs = node.getExpression();
    CFStore cmStoreBefore = typeFactory.getStoreBefore(rhs);
    CFValue cmValue = cmStoreBefore == null ? null : cmStoreBefore.getValue(lhs);
    AnnotationMirror cmAnno = null;
    if (cmValue != null) {
        for (AnnotationMirror anno : cmValue.getAnnotations()) {
            if (AnnotationUtils.areSameByName(anno, "org.checkerframework.checker.calledmethods.qual.CalledMethods")) {
                cmAnno = anno;
                break;
            }
        }
    }
    if (cmAnno == null) {
        cmAnno = typeFactory.top;
    }
    if (!calledMethodsSatisfyMustCall(mcValues, cmAnno)) {
        Element lhsElement = TreeUtils.elementFromTree(lhs.getTree());
        if (!checker.shouldSkipUses(lhsElement)) {
            checker.reportError(node.getTree(), "required.method.not.called", formatMissingMustCallMethods(mcValues), "field " + lhsElement.getSimpleName().toString(), lhsElement.asType().toString(), " Non-final owning field might be overwritten");
        }
    }
}
Also used : CFStore(org.checkerframework.framework.flow.CFStore) MethodTree(com.sun.source.tree.MethodTree) TypeCastNode(org.checkerframework.dataflow.cfg.node.TypeCastNode) ObjectCreationNode(org.checkerframework.dataflow.cfg.node.ObjectCreationNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) ThisNode(org.checkerframework.dataflow.cfg.node.ThisNode) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) NullLiteralNode(org.checkerframework.dataflow.cfg.node.NullLiteralNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) Node(org.checkerframework.dataflow.cfg.node.Node) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) TypeSystemError(org.checkerframework.javacutil.TypeSystemError) MustCallAnnotatedTypeFactory(org.checkerframework.checker.mustcall.MustCallAnnotatedTypeFactory) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) CFValue(org.checkerframework.framework.flow.CFValue) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TreePath(com.sun.source.util.TreePath) MustCall(org.checkerframework.checker.mustcall.qual.MustCall) NullLiteralNode(org.checkerframework.dataflow.cfg.node.NullLiteralNode)

Example 4 with MustCallAnnotatedTypeFactory

use of org.checkerframework.checker.mustcall.MustCallAnnotatedTypeFactory in project checker-framework by typetools.

the class ResourceLeakVisitor method visitMethod.

@Override
public Void visitMethod(MethodTree node, Void p) {
    ExecutableElement elt = TreeUtils.elementFromDeclaration(node);
    MustCallAnnotatedTypeFactory mcAtf = rlTypeFactory.getTypeFactoryOfSubchecker(MustCallChecker.class);
    List<String> cmcfValues = getCreatesMustCallForValues(elt, mcAtf, rlTypeFactory);
    if (!cmcfValues.isEmpty()) {
        // overwritten by a CMCF method, but the CMCF effect wouldn't occur.
        for (ExecutableElement overridden : ElementUtils.getOverriddenMethods(elt, this.types)) {
            List<String> overriddenCmcfValues = getCreatesMustCallForValues(overridden, mcAtf, rlTypeFactory);
            if (!overriddenCmcfValues.containsAll(cmcfValues)) {
                String foundCmcfValueString = String.join(", ", cmcfValues);
                String neededCmcfValueString = String.join(", ", overriddenCmcfValues);
                String actualClassname = ElementUtils.getEnclosingClassName(elt);
                String overriddenClassname = ElementUtils.getEnclosingClassName(overridden);
                checker.reportError(node, "creates.mustcall.for.override.invalid", actualClassname + "#" + elt, overriddenClassname + "#" + overridden, foundCmcfValueString, neededCmcfValueString);
            }
        }
    }
    return super.visitMethod(node, p);
}
Also used : ExecutableElement(javax.lang.model.element.ExecutableElement) MustCallAnnotatedTypeFactory(org.checkerframework.checker.mustcall.MustCallAnnotatedTypeFactory)

Example 5 with MustCallAnnotatedTypeFactory

use of org.checkerframework.checker.mustcall.MustCallAnnotatedTypeFactory in project checker-framework by typetools.

the class ResourceLeakTransfer method updateStoreWithTempVar.

/**
 * This method either creates or looks up the temp var t for node, and then updates the store to
 * give t the same type as node. Temporary variables are supported for expressions throughout this
 * checker (and the Must Call Checker) to enable refinement of their types. See the documentation
 * of {@link MustCallConsistencyAnalyzer} for more details.
 *
 * @param node the node to be assigned to a temporary variable
 * @param result the transfer result containing the store to be modified
 */
public void updateStoreWithTempVar(TransferResult<CFValue, CFStore> result, Node node) {
    // Must-call obligations on primitives are not supported.
    if (!TypesUtils.isPrimitiveOrBoxed(node.getType())) {
        MustCallAnnotatedTypeFactory mcAtf = rlTypeFactory.getTypeFactoryOfSubchecker(MustCallChecker.class);
        LocalVariableNode temp = mcAtf.getTempVar(node);
        if (temp != null) {
            rlTypeFactory.addTempVar(temp, node.getTree());
            JavaExpression localExp = JavaExpression.fromNode(temp);
            AnnotationMirror anm = rlTypeFactory.getAnnotatedType(node.getTree()).getAnnotationInHierarchy(rlTypeFactory.top);
            insertIntoStores(result, localExp, anm == null ? rlTypeFactory.top : anm);
        }
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) MustCallAnnotatedTypeFactory(org.checkerframework.checker.mustcall.MustCallAnnotatedTypeFactory) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode)

Aggregations

MustCallAnnotatedTypeFactory (org.checkerframework.checker.mustcall.MustCallAnnotatedTypeFactory)12 AnnotationMirror (javax.lang.model.element.AnnotationMirror)6 LocalVariableNode (org.checkerframework.dataflow.cfg.node.LocalVariableNode)6 ExecutableElement (javax.lang.model.element.ExecutableElement)5 MethodInvocationNode (org.checkerframework.dataflow.cfg.node.MethodInvocationNode)4 Node (org.checkerframework.dataflow.cfg.node.Node)4 ObjectCreationNode (org.checkerframework.dataflow.cfg.node.ObjectCreationNode)4 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)4 MethodTree (com.sun.source.tree.MethodTree)3 TypeElement (javax.lang.model.element.TypeElement)3 AssignmentNode (org.checkerframework.dataflow.cfg.node.AssignmentNode)3 FieldAccessNode (org.checkerframework.dataflow.cfg.node.FieldAccessNode)3 NullLiteralNode (org.checkerframework.dataflow.cfg.node.NullLiteralNode)3 ReturnNode (org.checkerframework.dataflow.cfg.node.ReturnNode)3 ThisNode (org.checkerframework.dataflow.cfg.node.ThisNode)3 TypeCastNode (org.checkerframework.dataflow.cfg.node.TypeCastNode)3 CFStore (org.checkerframework.framework.flow.CFStore)3 Element (javax.lang.model.element.Element)2 VariableElement (javax.lang.model.element.VariableElement)2 JavaExpression (org.checkerframework.dataflow.expression.JavaExpression)2