Search in sources :

Example 11 with Receiver

use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.

the class UpperBoundTransfer method refineSubtrahendWithOffset.

/**
 * Refines the subtrahend in a subtraction which is greater than or equal to a certain offset.
 * The type of the subtrahend is refined to the type of the minuend with the offset added. This
 * is case 10.
 *
 * <p>This is based on the fact that if {@code (minuend - subtrahend) >= offset}, and {@code
 * minuend + o < l}, then {@code subtrahend + o + offset < l}.
 *
 * <p>If {@code gtNode} is not a {@link NumericalSubtractionNode}, the method does nothing.
 *
 * @param gtNode the node that is greater or equal to the offset
 * @param offsetNode a node part of the offset
 * @param offsetAddOne whether to add one to the offset
 * @param in input of the transfer function
 * @param store location to store the refined types
 */
private void refineSubtrahendWithOffset(Node gtNode, Node offsetNode, boolean offsetAddOne, TransferInput<CFValue, CFStore> in, CFStore store) {
    if (gtNode instanceof NumericalSubtractionNode) {
        NumericalSubtractionNode subtractionNode = (NumericalSubtractionNode) gtNode;
        Node minuend = subtractionNode.getLeftOperand();
        UBQualifier minuendQual = getUBQualifier(minuend, in);
        Node subtrahend = subtractionNode.getRightOperand();
        UBQualifier subtrahendQual = getUBQualifier(subtrahend, in);
        UBQualifier newQual = subtrahendQual.glb(minuendQual.plusOffset(offsetNode, atypeFactory).plusOffset(offsetAddOne ? 1 : 0));
        Receiver subtrahendRec = FlowExpressions.internalReprOf(atypeFactory, subtrahend);
        store.insertValue(subtrahendRec, atypeFactory.convertUBQualifierToAnnotation(newQual));
    }
}
Also used : TypeCastNode(org.checkerframework.dataflow.cfg.node.TypeCastNode) NumericalMultiplicationNode(org.checkerframework.dataflow.cfg.node.NumericalMultiplicationNode) ArrayCreationNode(org.checkerframework.dataflow.cfg.node.ArrayCreationNode) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) CaseNode(org.checkerframework.dataflow.cfg.node.CaseNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) NumericalAdditionNode(org.checkerframework.dataflow.cfg.node.NumericalAdditionNode) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) Node(org.checkerframework.dataflow.cfg.node.Node) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode)

Example 12 with Receiver

use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.

the class UpperBoundTransfer method getUBQualifier.

/**
 * Returns the UBQualifier for node. It does this by finding a {@link CFValue} for node. First
 * it checks the store in the transfer input. If one isn't there, the analysis is checked. If
 * the UNKNOWN qualifier is returned, then the AnnotatedTypeMirror from the type factory is
 * used.
 *
 * @param n node
 * @param in transfer input
 * @return the UBQualifier for node
 */
private UBQualifier getUBQualifier(Node n, TransferInput<CFValue, CFStore> in) {
    QualifierHierarchy hierarchy = analysis.getTypeFactory().getQualifierHierarchy();
    Receiver rec = FlowExpressions.internalReprOf(atypeFactory, n);
    CFValue value = null;
    if (CFAbstractStore.canInsertReceiver(rec)) {
        value = in.getRegularStore().getValue(rec);
    }
    if (value == null) {
        value = analysis.getValue(n);
    }
    UBQualifier qualifier = getUBQualifier(hierarchy, value);
    if (qualifier.isUnknown()) {
        // The qualifier from the store or analysis might be UNKNOWN if there was some error.
        // For example,
        // @LTLength("a") int i = 4;  // error
        // The type of i in the store is @UpperBoundUnknown, but the type of i as computed by
        // the type factory is @LTLength("a"), so use that type.
        CFValue valueFromFactory = getValueFromFactory(n.getTree(), n);
        return getUBQualifier(hierarchy, valueFromFactory);
    }
    return qualifier;
}
Also used : CFValue(org.checkerframework.framework.flow.CFValue) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)

Example 13 with Receiver

use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.

the class UpperBoundTransfer method refineGTE.

/**
 * Case 9: if x &le; y, and y has a type that is related to the length of an array, then x has
 * the same type.
 */
@Override
protected void refineGTE(Node left, AnnotationMirror leftAnno, Node right, AnnotationMirror rightAnno, CFStore store, TransferInput<CFValue, CFStore> in) {
    UBQualifier leftQualifier = UBQualifier.createUBQualifier(leftAnno);
    UBQualifier rightQualifier = UBQualifier.createUBQualifier(rightAnno);
    UBQualifier refinedRight = rightQualifier.glb(leftQualifier);
    if (leftQualifier.isLessThanLengthQualifier()) {
        propagateToOperands((LessThanLengthOf) leftQualifier, right, in, store);
    }
    refineSubtrahendWithOffset(left, right, false, in, store);
    Receiver rightRec = FlowExpressions.internalReprOf(analysis.getTypeFactory(), right);
    store.insertValue(rightRec, atypeFactory.convertUBQualifierToAnnotation(refinedRight));
}
Also used : Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)

Example 14 with Receiver

use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.

the class UpperBoundTransfer method propagateToMultiplicationOperand.

/**
 * {@code other} times {@code node} is known to be {@code typeOfMultiplication}.
 *
 * <p>This implies that if {@code other} is positive, then {@code node} is {@code
 * typeOfMultiplication}. If {@code other} is greater than 1, then {@code node} is {@code
 * typeOfMultiplication} plus 1. These are cases 2 and 3, respectively.
 */
private void propagateToMultiplicationOperand(LessThanLengthOf typeOfMultiplication, Node node, Node other, TransferInput<CFValue, CFStore> in, CFStore store) {
    if (atypeFactory.hasLowerBoundTypeByClass(other, Positive.class)) {
        Long minValue = IndexUtil.getMinValue(other.getTree(), atypeFactory.getValueAnnotatedTypeFactory());
        if (minValue != null && minValue > 1) {
            typeOfMultiplication = (LessThanLengthOf) typeOfMultiplication.plusOffset(1);
        }
        UBQualifier qual = getUBQualifier(node, in);
        UBQualifier newQual = qual.glb(typeOfMultiplication);
        Receiver rec = FlowExpressions.internalReprOf(atypeFactory, node);
        store.insertValue(rec, atypeFactory.convertUBQualifierToAnnotation(newQual));
    }
}
Also used : Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)

Example 15 with Receiver

use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.

the class UpperBoundTransfer method propagateToSubtractionOperands.

/**
 * The subtraction node, {@code node}, is known to be {@code typeOfSubtraction}.
 *
 * <p>This means that the left node is less than or equal to the length of the array when the
 * right node is subtracted from the left node. Note that unlike {@link
 * #propagateToAdditionOperand(LessThanLengthOf, Node, Node, TransferInput, CFStore)} and {@link
 * #propagateToMultiplicationOperand(LessThanLengthOf, Node, Node, TransferInput, CFStore)},
 * this method takes the NumericalSubtractionNode instead of the two operand nodes. This
 * implements case 4.
 *
 * @param typeOfSubtraction type of node
 * @param node subtraction node that has typeOfSubtraction
 * @param in TransferInput
 * @param store location to store the refined type
 */
private void propagateToSubtractionOperands(LessThanLengthOf typeOfSubtraction, NumericalSubtractionNode node, TransferInput<CFValue, CFStore> in, CFStore store) {
    UBQualifier left = getUBQualifier(node.getLeftOperand(), in);
    UBQualifier newInfo = typeOfSubtraction.minusOffset(node.getRightOperand(), atypeFactory);
    UBQualifier newLeft = left.glb(newInfo);
    Receiver leftRec = FlowExpressions.internalReprOf(atypeFactory, node.getLeftOperand());
    store.insertValue(leftRec, atypeFactory.convertUBQualifierToAnnotation(newLeft));
}
Also used : Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)

Aggregations

Receiver (org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)55 AnnotationMirror (javax.lang.model.element.AnnotationMirror)19 Node (org.checkerframework.dataflow.cfg.node.Node)15 MethodInvocationNode (org.checkerframework.dataflow.cfg.node.MethodInvocationNode)14 FieldAccessNode (org.checkerframework.dataflow.cfg.node.FieldAccessNode)10 CFValue (org.checkerframework.framework.flow.CFValue)9 FlowExpressions (org.checkerframework.dataflow.analysis.FlowExpressions)8 FieldAccess (org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess)8 NumericalAdditionNode (org.checkerframework.dataflow.cfg.node.NumericalAdditionNode)8 NumericalSubtractionNode (org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode)8 ArrayList (java.util.ArrayList)7 TypeMirror (javax.lang.model.type.TypeMirror)7 ClassName (org.checkerframework.dataflow.analysis.FlowExpressions.ClassName)7 AssignmentNode (org.checkerframework.dataflow.cfg.node.AssignmentNode)7 Tree (com.sun.source.tree.Tree)6 TreePath (com.sun.source.util.TreePath)6 ArrayCreationNode (org.checkerframework.dataflow.cfg.node.ArrayCreationNode)6 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)6 MethodTree (com.sun.source.tree.MethodTree)5 CaseNode (org.checkerframework.dataflow.cfg.node.CaseNode)5