Search in sources :

Example 76 with JavaExpression

use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.

the class MustCallTransfer method visitStringConversion.

@Override
public TransferResult<CFValue, CFStore> visitStringConversion(StringConversionNode n, TransferInput<CFValue, CFStore> p) {
    // Implicit String conversions should assume that the String's type is
    // whatever the default for String is, not that the conversion is polymorphic.
    TransferResult<CFValue, CFStore> result = super.visitStringConversion(n, p);
    LocalVariableNode temp = getOrCreateTempVar(n);
    if (temp != null) {
        AnnotationMirror defaultStringType = getDefaultStringType(n);
        JavaExpression localExp = JavaExpression.fromNode(temp);
        insertIntoStores(result, localExp, defaultStringType);
    }
    return result;
}
Also used : CFValue(org.checkerframework.framework.flow.CFValue) AnnotationMirror(javax.lang.model.element.AnnotationMirror) CFStore(org.checkerframework.framework.flow.CFStore) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode)

Example 77 with JavaExpression

use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.

the class MustCallTransfer method visitMethodInvocation.

@Override
public TransferResult<CFValue, CFStore> visitMethodInvocation(MethodInvocationNode n, TransferInput<CFValue, CFStore> in) {
    TransferResult<CFValue, CFStore> result = super.visitMethodInvocation(n, in);
    updateStoreWithTempVar(result, n);
    if (!atypeFactory.getChecker().hasOption(MustCallChecker.NO_CREATES_MUSTCALLFOR)) {
        List<JavaExpression> targetExprs = CreatesMustCallForElementSupplier.getCreatesMustCallForExpressions(n, atypeFactory, atypeFactory);
        for (JavaExpression targetExpr : targetExprs) {
            AnnotationMirror defaultType = atypeFactory.getAnnotatedType(TypesUtils.getTypeElement(targetExpr.getType())).getAnnotationInHierarchy(atypeFactory.TOP);
            if (result.containsTwoStores()) {
                CFStore thenStore = result.getThenStore();
                lubWithStoreValue(thenStore, targetExpr, defaultType);
                CFStore elseStore = result.getElseStore();
                lubWithStoreValue(elseStore, targetExpr, defaultType);
            } else {
                CFStore store = result.getRegularStore();
                lubWithStoreValue(store, targetExpr, defaultType);
            }
        }
    }
    return result;
}
Also used : CFValue(org.checkerframework.framework.flow.CFValue) AnnotationMirror(javax.lang.model.element.AnnotationMirror) CFStore(org.checkerframework.framework.flow.CFStore) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression)

Example 78 with JavaExpression

use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.

the class MustCallTransfer 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 {@code node}.
 *
 * @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())) {
        LocalVariableNode temp = getOrCreateTempVar(node);
        if (temp != null) {
            JavaExpression localExp = JavaExpression.fromNode(temp);
            AnnotationMirror anm = atypeFactory.getAnnotatedType(node.getTree()).getAnnotationInHierarchy(atypeFactory.TOP);
            insertIntoStores(result, localExp, anm == null ? atypeFactory.TOP : anm);
        }
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode)

Example 79 with JavaExpression

use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.

the class AccumulationTransfer method accumulate.

/**
 * Updates the estimate of how many things {@code node} has accumulated.
 *
 * <p>If the node is an invocation of a method that returns its receiver, then its receiver's type
 * will also be updated. In a chain of method calls, this process will continue backward as long
 * as each receiver is itself a receiver-returning method invocation.
 *
 * <p>For example, suppose {@code node} is the expression {@code a.b().c()}, the new value (added
 * by the accumulation analysis because of the {@code .c()} call) is "foo", and b and c return
 * their receiver. This method will directly update the estimate of {@code a.b().c()} to include
 * "foo". In addition, the estimates for the expressions {@code a.b()} and {@code a} would have
 * their estimates updated to include "foo", because c and b (respectively) return their
 * receivers. Note that due to what kind of values can be held in the store, this information is
 * lost outside the method chain. That is, the returns-receiver propagated information is lost
 * outside the expression in which the returns-receiver method invocations are nested.
 *
 * <p>As a concrete example, consider the Called Methods accumulation checker: if {@code build}
 * requires a, b, and c to be called, then {@code foo.a().b().c().build();} will typecheck (they
 * are in one fluent method chain), but {@code foo.a().b().c(); foo.build();} will not -- the
 * store does not keep the information that a, b, and c have been called outside the chain. {@code
 * foo}'s type will be {@code CalledMethods("a")}, because only {@code a()} was called directly on
 * {@code foo}. For such code to typecheck, the Called Methods accumulation checker uses an
 * additional rule: the return type of a receiver-returning method {@code rr()} is {@code
 * CalledMethods("rr")}. This rule is implemented directly in the {@link
 * org.checkerframework.framework.type.treeannotator.TreeAnnotator} subclass defined in the Called
 * Methods type factory.
 *
 * @param node the node whose estimate should be expanded
 * @param result the transfer result containing the store to be modified
 * @param values the new accumulation values
 */
public void accumulate(Node node, TransferResult<CFValue, CFStore> result, String... values) {
    List<String> valuesAsList = Arrays.asList(values);
    // If dataflow has already recorded information about the target, fetch it and integrate
    // it into the list of values in the new annotation.
    JavaExpression target = JavaExpression.fromNode(node);
    if (CFAbstractStore.canInsertJavaExpression(target)) {
        CFValue flowValue = result.getRegularStore().getValue(target);
        if (flowValue != null) {
            Set<AnnotationMirror> flowAnnos = flowValue.getAnnotations();
            assert flowAnnos.size() <= 1;
            for (AnnotationMirror anno : flowAnnos) {
                if (atypeFactory.isAccumulatorAnnotation(anno)) {
                    List<String> oldFlowValues = atypeFactory.getAccumulatedValues(anno);
                    if (!oldFlowValues.isEmpty()) {
                        // valuesAsList cannot have its length changed -- it is backed by an
                        // array -- but if oldFlowValues is not empty, it is a new, modifiable list.
                        oldFlowValues.addAll(valuesAsList);
                        valuesAsList = oldFlowValues;
                    }
                }
            }
        }
    }
    AnnotationMirror newAnno = atypeFactory.createAccumulatorAnnotation(valuesAsList);
    insertIntoStores(result, target, newAnno);
    Tree tree = node.getTree();
    if (tree != null && tree.getKind() == Tree.Kind.METHOD_INVOCATION) {
        Node receiver = ((MethodInvocationNode) node).getTarget().getReceiver();
        if (receiver != null && atypeFactory.returnsThis((MethodInvocationTree) tree)) {
            accumulate(receiver, result, values);
        }
    }
}
Also used : CFValue(org.checkerframework.framework.flow.CFValue) AnnotationMirror(javax.lang.model.element.AnnotationMirror) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) Node(org.checkerframework.dataflow.cfg.node.Node) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) Tree(com.sun.source.tree.Tree)

Example 80 with JavaExpression

use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.

the class AliasingTransfer method visitAssignment.

/**
 * Case 1: For every assignment, the LHS is refined if the RHS has type {@literal @}Unique and is
 * a method invocation or a new class instance.
 */
@Override
public TransferResult<CFValue, CFStore> visitAssignment(AssignmentNode n, TransferInput<CFValue, CFStore> in) {
    Node rhs = n.getExpression();
    Tree treeRhs = rhs.getTree();
    AnnotatedTypeMirror rhsType = factory.getAnnotatedType(treeRhs);
    if (rhsType.hasAnnotation(Unique.class) && (rhs instanceof MethodInvocationNode || rhs instanceof ObjectCreationNode)) {
        // Do normal refinement.
        return super.visitAssignment(n, in);
    }
    // Widen the type of the rhs if the RHS's declared type wasn't @Unique.
    JavaExpression rhsExpr = JavaExpression.fromNode(rhs);
    in.getRegularStore().clearValue(rhsExpr);
    return new RegularTransferResult<>(null, in.getRegularStore());
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) ObjectCreationNode(org.checkerframework.dataflow.cfg.node.ObjectCreationNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) Node(org.checkerframework.dataflow.cfg.node.Node) ObjectCreationNode(org.checkerframework.dataflow.cfg.node.ObjectCreationNode) Tree(com.sun.source.tree.Tree) Unique(org.checkerframework.common.aliasing.qual.Unique) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) RegularTransferResult(org.checkerframework.dataflow.analysis.RegularTransferResult)

Aggregations

JavaExpression (org.checkerframework.dataflow.expression.JavaExpression)87 AnnotationMirror (javax.lang.model.element.AnnotationMirror)39 Node (org.checkerframework.dataflow.cfg.node.Node)23 StringToJavaExpression (org.checkerframework.framework.util.StringToJavaExpression)21 CFValue (org.checkerframework.framework.flow.CFValue)20 ExecutableElement (javax.lang.model.element.ExecutableElement)19 MethodInvocationNode (org.checkerframework.dataflow.cfg.node.MethodInvocationNode)19 ArrayList (java.util.ArrayList)15 CFStore (org.checkerframework.framework.flow.CFStore)15 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)13 JavaExpressionParseException (org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException)13 Tree (com.sun.source.tree.Tree)12 List (java.util.List)11 FieldAccess (org.checkerframework.dataflow.expression.FieldAccess)11 MethodTree (com.sun.source.tree.MethodTree)10 TreePath (com.sun.source.util.TreePath)10 HashMap (java.util.HashMap)10 Map (java.util.Map)9 Element (javax.lang.model.element.Element)9 VariableElement (javax.lang.model.element.VariableElement)9