Search in sources :

Example 16 with Receiver

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

the class UpperBoundTransfer method refineNeqSequenceLength.

/**
 * If lengthAccess node is an sequence length field or method access (optionally with a constant
 * offset subtracted) and the other node is less than or equal to that sequence length (minus
 * the offset), then refine the other node's type to less than the sequence length (minus the
 * offset). This is case 12.
 */
private void refineNeqSequenceLength(Node lengthAccess, Node otherNode, AnnotationMirror otherNodeAnno, CFStore store) {
    Receiver receiver = null;
    // If lengthAccess is "receiver.length - c" where c is an integer constant, stores c
    // into lengthOffset
    int lengthOffset = 0;
    if (lengthAccess instanceof NumericalSubtractionNode) {
        NumericalSubtractionNode subtraction = (NumericalSubtractionNode) lengthAccess;
        Node offsetNode = subtraction.getRightOperand();
        Long offsetValue = IndexUtil.getExactValue(offsetNode.getTree(), atypeFactory.getValueAnnotatedTypeFactory());
        if (offsetValue != null && offsetValue > Integer.MIN_VALUE && offsetValue <= Integer.MAX_VALUE) {
            lengthOffset = offsetValue.intValue();
            lengthAccess = subtraction.getLeftOperand();
        } else {
            // Subtraction of non-constant expressions is not supported
            return;
        }
    }
    if (NodeUtils.isArrayLengthFieldAccess(lengthAccess)) {
        FieldAccess fa = FlowExpressions.internalReprOfFieldAccess(atypeFactory, (FieldAccessNode) lengthAccess);
        receiver = fa.getReceiver();
    } else if (atypeFactory.getMethodIdentifier().isLengthOfMethodInvocation(lengthAccess)) {
        Receiver ma = FlowExpressions.internalReprOf(atypeFactory, lengthAccess);
        if (ma instanceof MethodCall) {
            receiver = ((MethodCall) ma).getReceiver();
        }
    }
    if (receiver != null && !receiver.containsUnknown()) {
        UBQualifier otherQualifier = UBQualifier.createUBQualifier(otherNodeAnno);
        String sequence = receiver.toString();
        // Check if otherNode + c - 1 < receiver.length
        if (otherQualifier.hasSequenceWithOffset(sequence, lengthOffset - 1)) {
            // Add otherNode + c < receiver.length
            UBQualifier newQualifier = UBQualifier.createUBQualifier(sequence, Integer.toString(lengthOffset));
            otherQualifier = otherQualifier.glb(newQualifier);
            for (Node internal : splitAssignments(otherNode)) {
                Receiver leftRec = FlowExpressions.internalReprOf(analysis.getTypeFactory(), internal);
                store.insertValue(leftRec, atypeFactory.convertUBQualifierToAnnotation(otherQualifier));
            }
        }
    }
}
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) FieldAccess(org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess) MethodCall(org.checkerframework.dataflow.analysis.FlowExpressions.MethodCall) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode)

Example 17 with Receiver

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

the class UpperBoundTransfer method propagateToAdditionOperand.

/**
 * Refines the type of {@code operand} to {@code typeOfAddition} plus {@code other}. If {@code
 * other} is non-negative, then {@code operand} also less than the length of the arrays in
 * {@code typeOfAddition}. If {@code other} is positive, then {@code operand} also less than the
 * length of the arrays in {@code typeOfAddition} plus 1. These are cases 5, 6, and 7.
 *
 * @param typeOfAddition type of {@code operand + other}
 * @param operand the Node to refine
 * @param other the Node added to {@code operand}
 * @param in TransferInput
 * @param store location to store the refined types
 */
private void propagateToAdditionOperand(LessThanLengthOf typeOfAddition, Node operand, Node other, TransferInput<CFValue, CFStore> in, CFStore store) {
    UBQualifier operandQual = getUBQualifier(operand, in);
    UBQualifier newQual = operandQual.glb(typeOfAddition.plusOffset(other, atypeFactory));
    /**
     * If the node is NN, add an LTEL to the qual. If POS, add an LTL.
     */
    if (atypeFactory.hasLowerBoundTypeByClass(other, Positive.class)) {
        newQual = newQual.glb(typeOfAddition.plusOffset(1));
    } else if (atypeFactory.hasLowerBoundTypeByClass(other, NonNegative.class)) {
        newQual = newQual.glb(typeOfAddition);
    }
    Receiver operandRec = FlowExpressions.internalReprOf(atypeFactory, operand);
    store.insertValue(operandRec, atypeFactory.convertUBQualifierToAnnotation(newQual));
}
Also used : Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) NonNegative(org.checkerframework.checker.index.qual.NonNegative)

Example 18 with Receiver

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

the class UpperBoundTransfer method refineEq.

/**
 * Refines the type of the left and right node to glb of the left and right annotation.
 */
private void refineEq(Node left, AnnotationMirror leftAnno, Node right, AnnotationMirror rightAnno, CFStore store) {
    UBQualifier leftQualifier = UBQualifier.createUBQualifier(leftAnno);
    UBQualifier rightQualifier = UBQualifier.createUBQualifier(rightAnno);
    UBQualifier glb = rightQualifier.glb(leftQualifier);
    AnnotationMirror glbAnno = atypeFactory.convertUBQualifierToAnnotation(glb);
    List<Node> internalsRight = splitAssignments(right);
    for (Node internal : internalsRight) {
        Receiver rightRec = FlowExpressions.internalReprOf(analysis.getTypeFactory(), internal);
        store.insertValue(rightRec, glbAnno);
    }
    List<Node> internalsLeft = splitAssignments(left);
    for (Node internal : internalsLeft) {
        Receiver leftRec = FlowExpressions.internalReprOf(analysis.getTypeFactory(), internal);
        store.insertValue(leftRec, glbAnno);
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) 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)

Example 19 with Receiver

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

the class UpperBoundTransfer method visitMethodInvocation.

/**
 * If n is a String.length() method invocation, then the type of s.length() is the glb
 * of @LTEqLengthOf("s") and the value of s.length() in the store. This is case 20.
 */
@Override
public TransferResult<CFValue, CFStore> visitMethodInvocation(MethodInvocationNode n, TransferInput<CFValue, CFStore> in) {
    if (atypeFactory.getMethodIdentifier().isLengthOfMethodInvocation(n)) {
        Receiver stringLength = FlowExpressions.internalReprOf(atypeFactory, n);
        if (stringLength instanceof MethodCall) {
            Receiver receiverRec = ((MethodCall) stringLength).getReceiver();
            Tree receiverTree = n.getTarget().getReceiver().getTree();
            // receiverTree is null when the receiver is implicit "this".
            if (receiverTree != null) {
                TransferResult<CFValue, CFStore> result = visitLengthAccess(n, in, receiverRec, receiverTree);
                if (result != null) {
                    return result;
                }
            }
        }
    }
    return super.visitMethodInvocation(n, in);
}
Also used : CFValue(org.checkerframework.framework.flow.CFValue) CFStore(org.checkerframework.framework.flow.CFStore) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) Tree(com.sun.source.tree.Tree) MethodCall(org.checkerframework.dataflow.analysis.FlowExpressions.MethodCall)

Example 20 with Receiver

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

the class UpperBoundTransfer method visitAssignment.

/**
 * Case 1: Refine the type of expressions used as an array dimension to be less than length of
 * the array to which the new array is assigned. For example, in "int[] array = new int[expr];",
 * the type of expr is @LTEqLength("array").
 */
@Override
public TransferResult<CFValue, CFStore> visitAssignment(AssignmentNode node, TransferInput<CFValue, CFStore> in) {
    TransferResult<CFValue, CFStore> result = super.visitAssignment(node, in);
    Node expNode = node.getExpression();
    // strip off typecast if any
    Node expNodeSansCast = (expNode instanceof TypeCastNode) ? ((TypeCastNode) expNode).getOperand() : expNode;
    // null if right-hand-side is not an array creation expression
    ArrayCreationNode acNode = (expNodeSansCast instanceof ArrayCreationNode) ? acNode = (ArrayCreationNode) expNodeSansCast : null;
    if (acNode != null) {
        // Right-hand side of assignment is an array creation expression
        List<Node> nodeList = acNode.getDimensions();
        if (nodeList.size() < 1) {
            return result;
        }
        Node dim = acNode.getDimension(0);
        UBQualifier previousQualifier = getUBQualifier(dim, in);
        Receiver arrayRec = FlowExpressions.internalReprOf(analysis.getTypeFactory(), node.getTarget());
        String arrayString = arrayRec.toString();
        LessThanLengthOf newInfo = (LessThanLengthOf) UBQualifier.createUBQualifier(arrayString, "-1");
        UBQualifier combined = previousQualifier.glb(newInfo);
        AnnotationMirror newAnno = atypeFactory.convertUBQualifierToAnnotation(combined);
        Receiver dimRec = FlowExpressions.internalReprOf(analysis.getTypeFactory(), dim);
        result.getRegularStore().insertValue(dimRec, newAnno);
        propagateToOperands(newInfo, dim, in, result.getRegularStore());
    }
    return result;
}
Also used : CFValue(org.checkerframework.framework.flow.CFValue) AnnotationMirror(javax.lang.model.element.AnnotationMirror) CFStore(org.checkerframework.framework.flow.CFStore) 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) LessThanLengthOf(org.checkerframework.checker.index.upperbound.UBQualifier.LessThanLengthOf) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) ArrayCreationNode(org.checkerframework.dataflow.cfg.node.ArrayCreationNode) TypeCastNode(org.checkerframework.dataflow.cfg.node.TypeCastNode)

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