Search in sources :

Example 1 with NumericalSubtractionNode

use of org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode 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 2 with NumericalSubtractionNode

use of org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode in project checker-framework by typetools.

the class UpperBoundTransfer method propagateToOperands.

/**
 * {@code node} is known to be {@code typeOfNode}. If the node is a plus or a minus then the
 * types of the left and right operands can be refined to include offsets. If the node is a
 * multiplication, its operands can also be refined. See {@link
 * #propagateToAdditionOperand(LessThanLengthOf, Node, Node, TransferInput, CFStore)}, {@link
 * #propagateToSubtractionOperands(LessThanLengthOf, NumericalSubtractionNode, TransferInput,
 * CFStore)}, and {@link #propagateToMultiplicationOperand(LessThanLengthOf, Node, Node,
 * TransferInput, CFStore)} for details.
 */
private void propagateToOperands(LessThanLengthOf typeOfNode, Node node, TransferInput<CFValue, CFStore> in, CFStore store) {
    if (node instanceof NumericalAdditionNode) {
        Node right = ((NumericalAdditionNode) node).getRightOperand();
        Node left = ((NumericalAdditionNode) node).getLeftOperand();
        propagateToAdditionOperand(typeOfNode, left, right, in, store);
        propagateToAdditionOperand(typeOfNode, right, left, in, store);
    } else if (node instanceof NumericalSubtractionNode) {
        propagateToSubtractionOperands(typeOfNode, (NumericalSubtractionNode) node, in, store);
    } else if (node instanceof NumericalMultiplicationNode) {
        if (atypeFactory.hasLowerBoundTypeByClass(node, Positive.class)) {
            Node right = ((NumericalMultiplicationNode) node).getRightOperand();
            Node left = ((NumericalMultiplicationNode) node).getLeftOperand();
            propagateToMultiplicationOperand(typeOfNode, left, right, in, store);
            propagateToMultiplicationOperand(typeOfNode, right, left, in, store);
        }
    }
}
Also used : NumericalAdditionNode(org.checkerframework.dataflow.cfg.node.NumericalAdditionNode) 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) NumericalMultiplicationNode(org.checkerframework.dataflow.cfg.node.NumericalMultiplicationNode) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode)

Example 3 with NumericalSubtractionNode

use of org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode 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 4 with NumericalSubtractionNode

use of org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode in project checker-framework by typetools.

the class OffsetEquation method createOffsetFromNode.

private static void createOffsetFromNode(Node node, AnnotationProvider factory, OffsetEquation eq, char op) {
    Receiver r = FlowExpressions.internalReprOf(factory, node);
    if (r instanceof Unknown || r == null) {
        if (node instanceof NumericalAdditionNode) {
            createOffsetFromNode(((NumericalAdditionNode) node).getLeftOperand(), factory, eq, op);
            createOffsetFromNode(((NumericalAdditionNode) node).getRightOperand(), factory, eq, op);
        } else if (node instanceof NumericalSubtractionNode) {
            createOffsetFromNode(((NumericalSubtractionNode) node).getLeftOperand(), factory, eq, op);
            char other = op == '+' ? '-' : '+';
            createOffsetFromNode(((NumericalSubtractionNode) node).getRightOperand(), factory, eq, other);
        } else {
            eq.error = node.toString();
        }
    } else {
        eq.addTerm(op, r.toString());
    }
}
Also used : NumericalAdditionNode(org.checkerframework.dataflow.cfg.node.NumericalAdditionNode) Unknown(org.checkerframework.dataflow.analysis.FlowExpressions.Unknown) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode)

Aggregations

NumericalAdditionNode (org.checkerframework.dataflow.cfg.node.NumericalAdditionNode)4 NumericalSubtractionNode (org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode)4 Receiver (org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)3 ArrayCreationNode (org.checkerframework.dataflow.cfg.node.ArrayCreationNode)3 AssignmentNode (org.checkerframework.dataflow.cfg.node.AssignmentNode)3 CaseNode (org.checkerframework.dataflow.cfg.node.CaseNode)3 FieldAccessNode (org.checkerframework.dataflow.cfg.node.FieldAccessNode)3 MethodInvocationNode (org.checkerframework.dataflow.cfg.node.MethodInvocationNode)3 Node (org.checkerframework.dataflow.cfg.node.Node)3 NumericalMultiplicationNode (org.checkerframework.dataflow.cfg.node.NumericalMultiplicationNode)3 TypeCastNode (org.checkerframework.dataflow.cfg.node.TypeCastNode)3 FieldAccess (org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess)1 MethodCall (org.checkerframework.dataflow.analysis.FlowExpressions.MethodCall)1 Unknown (org.checkerframework.dataflow.analysis.FlowExpressions.Unknown)1